stream 是 java 8 的一大亮點,專一於了集合的處理,包括抽取,過濾,轉化,聚合,化簡等,藉助新的 lambda 表達式,極大地簡化了流式處理的流程,提升了代碼的可讀性,同時支持併發和串行兩種模式,能夠很容易地寫出高性能的代碼java
stream 至關於一個高級版本的 iterator,iterator 只有簡單的遍歷功能,而 stream 在這個基礎上提供了抽取,過濾,轉化,聚合,化簡等豐富的流處理功能git
常見的操做主要中間操做和終止操做,一個流處理能夠會通過若干個中間操做和一個終止操做,中間操做返回的依然是一個流,終止操做得到一個特定的結果,中間操做是惰性的,在遇到終止操做以前,中間操做只是記錄一個操做步驟,不會從流中讀取任何數據github
// 從容器中建立 Stream<Integer> stream1 = List.of(1, 2, 3, 4, 5).stream(); Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5); // 建立隨機數 Stream<Integer> stream3 = new Random().ints().limit(10).boxed(); Stream<Integer> stream4 = ThreadLocalRandom.current().ints().limit(10).boxed(); // 文件流 Stream<String> stream5 = new BufferedReader(new FileReader("/tmp/test.txt")).lines(); // IntStream Stream<Integer> stream6 = IntStream.range(1, 10).boxed(); // generate Stream<Integer> stream7 = Stream.generate(() -> (int) System.currentTimeMillis()).limit(10); // iterate Stream<Integer> stream8 = Stream.iterate(1, x -> x + 1).limit(10); Stream<Integer> stream9 = Stream.iterate(1, x -> x < 10, x -> x + 1);
終止操做表明一個計算的結果,常見的終止操做以下:數據庫
forEach
: 遍歷元素forEachOrdered
: 按順序遍歷元素,主要在併發場景下使用toArray
: 將流輸出到數組中collect
: 收集流,能夠輸出到指定的 Collector
中,Collectors
中自帶了 toList
,toSet
等 Collector
anyMatch
: 任意元素知足謂詞,返回 trueallMatch
: 全部元素知足謂詞,返回 truenoneMatch
: 全部元素都不知足謂詞,返回 truecount
: 元素數量findFirst
: 返回第一個元素findAny
: 返回任意一個元素min
: 返回最小元素max
: 返回最大元素reduce
: 聚合,將流中全部的數據聚合成一個值Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).forEach(System.out::print); Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).forEachOrdered(System.out::print); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).toArray(), equalTo(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).collect(Collectors.toList()), equalTo(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9))); assertFalse(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).anyMatch(x -> x > 10)); assertTrue(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).allMatch(x -> x < 10)); assertTrue(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).noneMatch(x -> x > 10)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).count(), 9); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).findFirst().orElse(0), Integer.valueOf(1)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).findAny().orElse(0), Integer.valueOf(1)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).iterator().next(), Integer.valueOf(1)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).max(Comparator.comparingInt(x -> x)).orElse(0), Integer.valueOf(9)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).min(Comparator.comparingInt(x -> x)).orElse(0), Integer.valueOf(1)); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce((x, y) -> x + y).orElse(0), Integer.valueOf(45));
map
: 轉化,將流中元素按照 Founction 映射成另外一種元素filter
: 過濾,將不符合條件的元素從流中刪除distinct
: 去重,去掉重複元素sorted
: 排序limit
: 最多取元素的個數skip
: 跳過前 n 個元素peek
: 和 forEach 操做相似,但依然會返回當前流takeWhile
: 獲取元素直到不知足條件dropWhile
: 丟棄元素直到知足條件assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).map(x -> x * x).collect(Collectors.toList()), equalTo(List.of( 1, 4, 9, 16, 25, 36, 49, 64, 81 ))); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).filter(x -> x % 2 == 0).collect(Collectors.toList()), equalTo(List.of( 2, 4, 6, 8 ))); assertThat(Stream.of(4, 1, 2, 1, 2, 4, 3, 3).distinct().collect(Collectors.toList()), equalTo(List.of( 4, 1, 2, 3 ))); assertThat(Stream.of(6, 4, 7, 3, 2, 9, 1, 5, 8).sorted().collect(Collectors.toList()), equalTo(List.of( 1, 2, 3, 4, 5, 6, 7, 8, 9 ))); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).limit(3).collect(Collectors.toList()), equalTo(List.of( 1, 2, 3 ))); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).skip(6).collect(Collectors.toList()), equalTo(List.of( 7, 8, 9 ))); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).peek(System.out::println).collect(Collectors.toList()), equalTo(List.of( 1, 2, 3, 4, 5, 6, 7, 8, 9 ))); assertEquals(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).mapToInt(x -> x * x).sum(), 285); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).takeWhile(x -> x < 5).collect(Collectors.toList()), equalTo(List.of( 1, 2, 3, 4 ))); assertThat(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).dropWhile(x -> x < 5).collect(Collectors.toList()), equalTo(List.of( 5, 6, 7, 8, 9 )));
相似於數據庫中 group by
的操做,流處理也支持 group by
,能根據對象中的某個字段聚合數組
class Student { private final String grade; private final String name; private final int chinese; private final int english; private Student(String grade, String name, int chinese, int english) { this.grade = grade; this.name = name; this.chinese = chinese; this.english = english; } @Override public String toString() { return "[" + grade + " " + name + " " + chinese + " " + english + "]"; } } Random random = new Random(); Stream<Student> stream = Stream.generate(() -> new Student( "grade" + Math.abs(random.nextInt() % 4 + 1), "student" + Math.abs(random.nextInt() % 1000), Math.abs(random.nextInt() % 30 + 70), Math.abs(random.nextInt() % 30 + 70) ) ); Map<String, List<Student>> map = stream.limit(10).collect(Collectors.groupingBy( x -> x.grade, Collectors.toList() )); map.forEach((k, v) -> { System.out.println(k + " => " + v); });