天天看點

java Stream的學習與簡單練習java Stream的學習與簡單練習

java Stream的學習與簡單練習

什麼是stream

  • Stream 流是java 1.8 的新特性之一。
  • stream 是處理 :集合、數組、IO流等資料的抽象概念,簡單來說就是處理資料。并傳回一個新的流(不修改原有的資料,而是講處理後的的資料放在另一個流中 – 惰性操作)。最後以終止操作結尾。

Stream 與 Collection 流和集合的差別

  • 沒有存儲。流不是存儲元素的資料結構;相反,它通過計算操作的管道傳送來自資料結構、數組、生成器函數或 I/O 通道等源的元素。
  • 對流的操作會産生結果,但不會修改其源
  • 許多流操作,例如過濾、映射或重複删除,可以懶惰地實作
  • 集合有大小的限制,而流沒有
  • 流中的元素在流的生命周期中隻會被通路一次

獲得流的方式

  • 從一個Collection通過stream()和 parallelStream()方法
  • 從一個數組通過Arrays.stream(Object[])
  • 流類上的靜态工廠方法 Stream.of(Object[]) 或 Stream.iterate(Object, UnaryOperator)
  • 檔案的lines() BufferedReader.lines();
  • 可以從以下位置獲得随機數流Random.ints();
  • ……

流的操作和管道

  • 流操作分為中間操作和 終端操作,結合起來形成流管道。一個流管道由一個源(例如一個 Collection、一個數組、一個生成器函數或一個 I/O 通道)組成;後跟零個或多個中間操作,例如 Stream.filter或Stream.map;和終端操作,例如Stream.forEach或Stream.reduce
  • 中間操作傳回一個新的流。執行中間操作,例如 filter()實際上并不執行任何過濾,而是建立一個新流,該流在周遊時包含與給定謂詞比對的初始流的元素。管道源的周遊直到管道的終端操作被執行後才開始。
  • 有狀态:指元素的處理不受之前元素的影響。如:filter and map(過濾和映射 惰性操作)
  • 無狀态:指操作隻有拿到所有元素之後才能繼續下去。如:distinct和sorted(去重和排序)
  • 并行性:jdk預設串行,也可以在初始建立流時選在串行還是并行。如Collection有方法 Collection.stream()和Collection.parallelStream()

Stream 簡單操作示例(一下示例以常用的集合為例)

  • 代碼一

/**			過濾空字元串  、計算空字元的個數
         * stream().filter(過濾的條件) 過濾
         * String -> !String.isempty  過濾不為空的字元
         * collect(Collectors.toList()) 将過濾好的資料專入集合
         * collect(Collectors.joining(",")) 用逗号拼字元集合資料并轉為String類型
         */
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//過濾空字元串
List<String> filterStrings = strings.stream()
									.filter(String -> !String.isEmpty()) 
									.collect(Collectors.toList());
//空字元串的個數
 long count = strings.stream().filter(String -> String.isEmpty()).count();
 //用逗号拼接的字元串
 String str = strings.stream()
 					.filter(s -> !s.isEmpty())
 					.collect(Collectors.joining(","));
  System.out.println("用逗号拼接的字元串:"+str);
  System.out.println("空字元串的個數 "+count);
  System.out.println("不為空的字元串集合: "+filterStrings); 					
           
  • 運作結果
用逗号拼接的字元串:abc,bc,efg,abcd,jkl
空字元串的個數 2
不為空的字元串集合: [abc, bc, efg, abcd, jkl]
           

代碼二

/**
  *  stream().map :映射集合中每個元素對用的結果
  *  i-> i+10 :  i 代表集合中的每個元素  -> :映射處理轉換資料i  i+10 : 每個元素i 結果
  *  collect(Collectors.toList())将處理好的元素存入集合
  *  nums.forEach(System.out :: println); forEach 周遊nums 整形集合
*/
  List<Integer> nums = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 // 周遊nums 集合
 nums.forEach(System.out :: println);
 //将集合中的每個元素都+10
 List<Integer> mapNums = nums.stream()
 							 .map(i -> i+10)
 							 .collect(Collectors.toList());
System.out.println(mapNums);
//也可以先過濾在映射
List<Integer> numOne = nums.stream()
						   .filter(i -> i<=2 )
						   .map(i -> i*i)
						   .collect(Collectors.toList());
numOne.forEach(System.out::println);
           
  • 運作結果
3
2
2
3
7
3
5

[13, 12, 12, 13, 17, 13, 15]

4
4
           

代碼三

/**
   * mapToInt((s) -> Integer.valueOf(s)) 講stringNums 中的string類型資料轉為int
   * summaryStatistics() 傳回一個狀态對象,用于收集計數、最小值、最大值、總和和平均值等統計資訊。
   */
List<String> stringNums = Arrays.asList("3", "2", "2", "3", "7", "3", "5");
IntSummaryStatistics statistics = stringNums.stream().mapToInt((s) -> Integer.valueOf(s)).summaryStatistics();
System.out.println(statistics.getCount());;
System.out.println("max: "+statistics.getMax());
System.out.println("min: "+statistics.getMin());
System.out.println("sum: "+statistics.getSum());
System.out.println("Class: "+statistics.getClass());
System.out.println("avg: "+statistics.getAverage());
           
  • 運作結果
count: 7
max: 7
min: 2
sum: 25
Class: class java.util.IntSummaryStatistics
avg: 3.5714285714285716