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