Stream 允許我們以聲明的方式處理資料。
簡介
- 在 Java 中,集合和數組是兩種常見的資料結構
- 類似于 SQL 語句從資料庫查詢資料的形式,Stream 提供了對 Java 集合操作和表示的高度抽象。
- 要處理的元素集合被視為流,在流水線中進行傳輸。并可在流水線各節點處理這些元素,例如過濾,排序和聚合。
特點
- 不占用空間。Stream 隻是資料源的視圖,表現形式可以是數組、容器或者I/O通道。
- 流操作資料源,不會改變資料源。 例如: 過濾Stream後不會删除過濾的元素,而是生成一個新的不包含過濾元素的Stream
- 懶加載。 對Stream的操作隻有在需要的時候才會執行。
- 不可重複消費。 在流的生命周期中,元素僅能被通路一次。
操作
流的建立
- 集合建立
List<String> list = Arrays.asList("Hello", "Word", "!"); Stream<String> stream = list.stream();
- Stream自帶的方法
Stream<String> streams = Stream.of("Hello", "Word", "!");
中間操作
- 多個中間操作組合形成流水線,中間操作傳回的是一個新的Stream.
- filter
System.out.println(streams.stream().filter((e) -> "Hello".equals(e))); strings.stream().filter(e -> !e.isEmpty()).forEach(System.out::println);
- 映射
- map(Function f):接收一個函數作為參數,該函數會被應用到流中的每個元素上,并将其映射成一個新的元素。
- flatMap(Function> mapper):接收一個函數作為參數,将流中的每個值都換成另一個流,然後把所有流連接配接成一個流
List<String> numbers = Arrays.asList("a","b"); numbers.stream().map(i -> i + i).forEach(System.out::println); Stream<List<String>> stream2 = Stream.of(Arrays.asList("H","E"), Arrays.asList("L", "L", "O")); stream2.flatMap(list -> list.stream()).forEach(System.out::println);
- limit/skip
- limit 傳回 Stream 中的前 N 個元素。skip 舍棄 Stream 中的前 N 個元素。
List<String> numbers = Arrays.asList("a","b"); numbers.stream().limit(1).forEach(System.out::println); numbers.stream().skip(1).forEach(System.out::println);
- 排序
- sorted():自然排序使用Comparable的int compareTo(T o)方法
- sorted(Comparator com):定制排序使用Comparator的int compare(T o1, T o2)方法
List<String> numbers = Arrays.asList("b","a"); numbers.stream().sorted().forEach(System.out::println); numbers.stream().sorted((x,y) -> y.compareTo(x)).forEach(System.out::println);
- distinct
- 去重
List<String> numbers = Arrays.asList("b","a","b"); numbers.stream().distinct().forEach(System.out::println);
- reduce
- 累加
System.out.println("=====reduce:将流中元素反複結合起來,得到一個值=========="); Stream<Integer> stream = Stream.iterate(1, x -> x+1).limit(200); //stream.forEach(System.out::println); Integer sum = stream.reduce(10,(x,y)-> x+y); System.out.println(sum);
終端操作
- 傳回值不為Stream 的為終端操作(立即求值),終端操作不支援鍊式調用,會觸發實際計算
- 執行過末端操作以後,Stream 不可再次使用,且不允許執行任何中間操作。
- forEach
- 周遊
List<String> numbers = Arrays.asList("b","a","b"); numbers.stream().forEach(System.out::println);
- count
- 統計個數
List<String> numbers = Arrays.asList("b","a"); numbers.stream().count();
- collect
- 組合,傳回對應的類型,包括list,set,treeset ,map 等
List<String> numbers = Arrays.asList("b","a"); numbers = numbers.stream().sorted().collect(Collectors.toList()); List<lambdaDemo> lambdaDemos = Arrays.asList(new lambdaDemo("zhang","bing",1), new lambdaDemo("li","hua",2)); Map<Integer,String> maps = lambdaDemos.stream().collect(Collectors.toMap(lambdaDemo::getAge,lambdaDemo::getName)); System.out.println(maps); //以年齡為唯一值, public static Map<Integer,lambdaDemo> check(List<lambdaDemo> lambdaDemos){ return lambdaDemos.stream().collect(Collectors.toMap(lambdaDemo::getAge, Function.identity(), (existing, replacement) -> existing)); }
- 分組和分區
- Collectors.groupingBy()對元素做group操作。
- Collectors.partitioningBy()對元素進行二分區操作。
public static void test9() { List<lambdaDemo> lambdaDemos = Arrays.asList(new lambdaDemo("zhang","黑人",65), new lambdaDemo("li","黑人",40), new lambdaDemo("liu","白人",40)); System.out.println("=======根據人的膚色進行分組=========================="); Map<String, List<lambdaDemo>> map = lambdaDemos.stream().collect(Collectors.groupingBy(lambdaDemo::getName)); System.out.println(map); System.out.println("=======根據人的年齡範圍多級分組=========================="); Map<Integer, Map<String, List<lambdaDemo>>> map2 = lambdaDemos.stream().collect(Collectors.groupingBy(lambdaDemo::getAge, Collectors.groupingBy( ( p ) -> { if ( p.getAge() > 60 ) { return "老年人"; } else { return "年輕人"; } } ) )); System.out.println(map2); } public static void test10() { List<lambdaDemo> lambdaDemos = Arrays.asList(new lambdaDemo("zhang","黑人",60), new lambdaDemo("li","黑人",2), new lambdaDemo("liu","白人",3)); System.out.println("========根據人的年齡是否大于40進行分區========================"); Map<Boolean, List<lambdaDemo>> map = lambdaDemos.stream().collect(Collectors.partitioningBy(p -> p.getAge() > 40)); System.out.println(map); }
github部落格清單位址
github歡迎關注公衆号,檢視更多内容 :
