天天看點

Java1.8新特性 -- Stream流總結

Stream流

1.8 java推出的新特性

  • Stream流的出現,可以讓我們

    減少代碼量

    ,使得

    代碼更加的優雅

    ,同時會使得

    代碼不易閱讀

傳統寫法與Stream流的比較

使用傳統的寫法:

//建立一個集合
	List<String> list = new ArrayList<>();
	//添加
	list.add("張三");
	list.add("李四");
	list.add("王五");
	//周遊
	for(String name : list){
		System.out.println(name);
	}
           

這樣會輸出

Java1.8新特性 -- Stream流總結

使用Stream的寫法:

//建立一個集合
	List<String> list = new ArrayList<>();
	//添加
	list.add("張三");
	list.add("李四");
	list.add("王五");
	//周遊
	list.stream().forEach(name-> System.out.println(name));
           

同樣會輸出

Java1.8新特性 -- Stream流總結

或許這樣還不太容易看得出變得更加友善了…

提出一個新的需求

1. 對list集合中的元素進行過濾,隻要以張開頭的元素,存儲到一個新的集合A中
2. 并且要求隻要姓名長度為三的人,存儲到一個新集合B中
3. 周遊新集合B
           
  • 使用傳統的寫法:
//建立一個集合
		List<String> list = new ArrayList<>();
        //添加
        list.add("張三");
        list.add("張三豐");
        list.add("李白");
        list.add("李清照");
        list.add("周傑倫");
        list.add("張老頭");
        
		//對list集合中的元素進行過濾,隻要以張開頭的元素,存儲到一個新的集合中
		List<String> listA = new ArrayList<>();
		for(String name : list){
			if(name.startsWith("張")){
				listA .add(name);
			}
		}
		
		//隻要姓名長度為三的人,存儲到一個新集合中
		List<String> listB = new ArrayList<>();
		for(String name: listA){
			if(name.length() == 3){
				listB.add(name);
			}
		}
		
		//周遊2的新集合
		for(String name: listB){
				System.out.println(name);
			}
		
           

輸出結果:

Java1.8新特性 -- Stream流總結
  • 使用Stream的寫法:
//建立一個集合
		List<String> list = new ArrayList<>();
        //添加
        list.add("張三");
        list.add("張三豐");
        list.add("李白");
        list.add("李清照");
        list.add("周傑倫");
        list.add("張老頭");
        
		//對list集合中的元素進行過濾,隻要以張開頭的元素,存儲到一個新的集合中
		//隻要姓名長度為三的人,存儲到一個新集合中
		//周遊新集合
		list.stream()
			.filter(name->name.startsWith("張"))
			.filter(name->name.length() == 3)
			.forEach(name->System.out.println(name));
		
           

輸出結果同樣是

Java1.8新特性 -- Stream流總結

通過這個列子就能很好的看出Steram流的

代碼量少

,

簡潔

,同時缺點相對于傳統的方法,

代碼變得不易閱讀

如何擷取Stream流

  • 一. 可以通過API文檔在

    java.util.stream

    找到它的

    Interface Stream<T>

    接口,使用靜态方法of來進行擷取
Stream<String> stream1 = Stream.of("張三","李四","王五");

Stream<Integer> stream2 = Stream.of(1,2,3);

//使用數組擷取Stream流
String[] str = {"張三","李四","王五"};
stream3 = Stream.of(str);

Integer[] in = {1,2,3};
stream3 = Stream.of(in);

           
  • 二.把集合轉換成Stream流
//可以改成Integer等别的類型

List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();

Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();

//map隻能進行轉換然後存取
Map<String,String> map = new HashMap<>();

//1. 換取鍵,存儲到Set集合中
Set<String> keySet = map.keySet();
Stream<String> stream3 = keySet.stream();

//2. 擷取值,存儲到Collection集合中
Collection<String> values = map.values();
Stream<String> stream4 = values.stream();

//3. 擷取鍵值對(鍵與值的映射關系 enterSet)
Set<Map.Entry<String, String>> entries = map.entrySet();
Stream<Map.Entry<String, String>> stream5 = entries.stream();
           

Stream流的一些常用的方法

  1. forEach: 周遊
Stream<T> forEach(Consumer<? super T> action)

Consumer<? super T> action 是一個抽象方法,用于消費的 
由于是抽象方法是以我們可以使用lambda表達式

例子:
	//建立一個集合
	List<String> list = new ArrayList<>();
	
	//添加
	list.add("張三");
	list.add("李四");
	list.add("王五");
	
	//周遊
	list.stream().forEach(name-> System.out.println(name));
	
	//name-> System.out.println(name)是一個lambda表達式
           

結果:

Java1.8新特性 -- Stream流總結
  1. filter: 是否比對(條件)
Stream<T> filter(Predicate<? super T> predicate)

Predicate<? super T> predicate 是一個抽象方法 傳回的是一個boolean值

例子:	
	//建立一個集合
	List<String> list = new ArrayList<>();
	
	//添加
	list.add("張三");
	list.add("李四");
	list.add("張三豐");
	list.add("花無缺");
	
	//開頭是否有張
	//姓名是否三個字
	list.stream().filter(name->name.startsWith("張"))
				.filter(name->name.length() == 3)
				.forEach(name->System.out.println(name));
	
	//以下都是lambda表達式			
	//name->name.startsWith("張")   startsWith方法是測試此字元串是否以指定的字首開頭。 
	//name->name.length() == 3
	//name->System.out.println(name)
           

輸出結果

Java1.8新特性 -- Stream流總結
  1. map: 轉換資料類型
<R> Stream<R> map(Function<? super T,? extends R> mapper)

Function<? super T,? extends R> mapper 是一個抽象方法,可以把參數1轉換成參數2的資料類型

例子:
		//擷取一個String類型的Stream流
        Stream<String> stream = Stream.of("1", "2", "3", "4");
        
		//将String類型轉換成Integer類型,不僅可以轉換成Integer類型也可以轉換成對象
      Stream<Integer> stream2  = stream.map(s->Integer.parseInt(s));
       
       //周遊stream2
       stream2.forEach(in-> System.out.println(in));
       
	//其實也可以連着寫
	//stream.map(s->Integer.parseInt(s)).forEach(in-> System.out.println(in));

	以下都是lambda表達式			
	//s->Integer.parseInt(s)
	//in-> System.out.println(in)
	
           

輸出結果:

Java1.8新特性 -- Stream流總結
  1. count: 擷取數量
例子:
	//建立一個集合
	List<String> list = new ArrayList<>();
	
	//添加
	list.add("張三");
	list.add("李四");
	list.add("張三豐");
	list.add("花無缺");
	
	//擷取數量
	long count = list.stream().count();
	System.out.println(count);
           

輸出結果:

Java1.8新特性 -- Stream流總結
  1. limit: 截取
例子:
	String[] str = {"張三","李四","王五","趙六","田七"};
	
	Stream<String> stream = Stream.of(str);
	
	Stream<String> stream2 = stream.limit(3);	//截取1-3的資料
	
	stream2 .forEach(str->System.out.println(str));
           

結果:

Java1.8新特性 -- Stream流總結
  1. skip: 用來跳過元素
例子:
		String[] str = {"張三","李四","王五","趙六","田七"};
	
		Stream<String> stream = Stream.of(str);
		
		Stream<String> stream2 = stream.skip(3);	//跳過前3個
		
		stream2 .forEach(name->System.out.println(name));
           

結果:

Java1.8新特性 -- Stream流總結

7. concat:

<R,A> R collect(Collector<? super T,A,R> collector)  

Collector<? super T,A,R> collector
 是一個抽象方法,可以将兩個stream流連接配接起來

例子:
	String[] str1 = {"張三","李四","王五","趙六","田七"};
	String[] str2 = {"李白","杜甫","王安石","白居易"};
	
	Stream<String> stream1 = Stream.of(str1);

    Stream<String> stream2 = Stream.of(str2);

    Stream<String> stream = Stream.concat(stream1,stream2);
    
    stream.forEach(name->System.out.println(name));
           

結果:

Java1.8新特性 -- Stream流總結

注意:

  • Stream流使用一次後,就會關閉,如果重新使用就會報錯(

    Stream流隻能使用一次

    )

    例如:

String[] str = {"張三","李四","王五","趙六","田七"};
		
        Stream<String> stream = Stream.of(str);
        //使用第一次
        stream.skip(1);
         //使用第二次
        stream.forEach(name-> System.out.println(name));
           

報錯:

IllegalStateException: stream has already been operated upon or closed