Stream 的常用操作

Intermediate :

一個流可以後面跟隨零個或多個 intermediate 操作。其目的主要是打開流,做出某種程度的數據映射/過濾,然後返回一個新的流,交給下一個操作使用。這類操作都是惰性化的(lazy),就是說,僅僅調用到這類方法,並沒有真正開始流的遍歷。

 

map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel(並行)、 sequential、 unordered

 

map (對元素進行處理並返回處理結果)

 

Stream<Integer> simpleStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

//Intermediate(媒介) 惰性求值方法(N)

simpleStream.map(x->x+5+"\t").forEach(System.out::print);

控制檯輸出

mapToInt、mapToLong、mapToDouble 都是在map方法的基礎上返回對應類型的專業化流

//在map操作的基礎上返回該數據類型對應的專業化Stream

IntStream intStream = simpleStream.mapToInt(x -> x + 5);

DoubleStream doubleStream = simpleStream.mapToDouble(x -> x + 5);

LongStream longStream = simpleStream.mapToLong(x -> x + 5);

例:小寫元素轉大寫

//小寫元素轉大寫

Stream<String> stringStream = Stream.of("a", "b", "c", "d");

//stringStream.map(x->x.toUpperCase()).forEach(System.out::println);

//可簡寫

stringStream.map(String::toUpperCase).forEach(System.out::println);

 

 

filter(過濾)

//filter 依據lambda過濾Stream元素

long count = simpleStream.filter(x -> x > 4).count();

System.out.println(count);

 

distinct​(元素去重)

//distinct 元素去重,對於有序流不影響其排序

Stream<Integer> distinctStream = Stream.of(1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9);

distinctStream.distinct().map(x->x+"\t").forEach(System.out::print);

控制檯輸出

 

sorted(元素排序)

//sorted 元素排序,按照自然循序或compare規則排序

//自然順序排序

Stream<Integer> sortedStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

sortedStream.sorted().map(x->x+"\t").forEach(System.out::print);

System.out.println();

//倒序

Stream<Integer> sortedStream1 = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

sortedStream1.sorted(Comparator.reverseOrder()).map(x->x+"\t").forEach(System.out::print);

控制檯輸出

 

limit(截取前N個元素)

//返回由此流的元素組成的流,截短長度不要超過maxSize 。

Stream<Integer> limitStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

limitStream.limit(3).map(x->x+"\t").forEach(System.out::print);

控制檯輸出

 

skip​(截取後N個元素)

//在丟棄流的第一個n元素後,返回由該流的剩餘元素組成的流。 如果此流包含少於n元素,那麼將返回一個空流。

Stream<Integer> skip​Stream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

skip​Stream.skip(3).map(x->x+"\t").forEach(System.out::print);

控制檯輸出

 

Terminal :

一個流只能有一個 terminal 操作,當這個操作執行後,流就被使用“光”了,無法再被操作。所以這必定是流的最後一個操作。Terminal 操作的執行,纔會真正開始流的遍歷,並且會生成一個結果,或者一個 side effect。

 

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

 

forEach/​forEachOrder(遍歷)

forEach是並行處理的,forEachOrder是按順序處理的,顯然前者速度更快。

 

toArray(返回一個數組對象)

//toArray

Stream<Integer> arrayStream = Stream.of(1, 5, 9, 7, 3, 6, 4, 8, 2,0);

//無參,返回一個Object數組

Object[] objects = arrayStream.toArray();

//發生器函數採用一個整數,它是所需數組的大小,併產生一個所需大小的數組

//構造引用 ,限定返回數組類型

String[] strings = arrayStream.toArray(String[]::new);

 

reduce(累積-減少,總和,最小,最大,平均和字符串連接等)

 

F//reduce 減少操作

//T reduce​(T identity,BinaryOperator<T> accumulator)

// 使用提供的身份值和associative累積功能對此流的元素執行reduction ,並返回減小的值

IntStream range = IntStream.rangeClosed(1, 10);

int reduce = range.reduce(0, Integer::sum);

System.out.println(reduce);

//等價於

IntStream range1 = IntStream.rangeClosed(1, 10);

int reduce1 = range1.reduce(0, (a, b) -> a + b);

System.out.println(reduce1);

 

//Optional<T> reduce​(BinaryOperator<T> accumulator)

IntStream range2 = IntStream.rangeClosed(1, 10);

OptionalInt reduce2= range2.reduce((a, b) -> a + b);

int asInt = reduce2.getAsInt();

System.out.println(asInt);

 

collect (將Stream轉換爲其他數據結構)

//collect 將Stream轉換爲其他數據結構

//提供了兩個重載的方法

 

//<R> R collect​(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)

//supplier:一個能創造目標類型實例的方法。

// accumulator:一個將當元素添加到目標中的方法。

// combiner:一個將中間狀態的多個結果整合到一起的方法(併發的時候會用到)

IntStream stream = Arrays.stream(range(1, 10).toArray());

ArrayList<Object> collect = stream.collect(ArrayList::new, List::add, List::addAll);

System.out.println(collect.toString());

 

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

//注:Stream的特化IntStream,LongStream,DoubleStream不具備該方法

List<String> strings = Arrays.asList("a", "b", "c", "d", "e");

//可以通過Collectors提供的靜態方法返回各種數據,其實就是另一個方法的封裝簡化

//List->Set

Set<String> collect1 = strings.stream().collect(Collectors.toSet());

System.out.println(collect1.toString());

//List->Map

Map<String, String> collect3 = strings.stream().collect(Collectors.toMap(x -> x.toUpperCase(), y -> y.toString()));

System.out.println(collect3.toString());

 

anyMatch/allMatch/noneMatch (是否滿足條件)

 

IntStream stream1 = Arrays.stream(range(1, 10).toArray());

//anyMatch 表示,判斷的條件裏,任意一個元素成功,返回true

System.out.println(stream1.anyMatch(x->x>5)); //返回true

 

//allMatch 表示,判斷條件裏的元素,所有的都是,返回true

System.out.println(stream1.allMatch(x->x>0)); //返回true

 

//noneMatch 跟allMatch相反,判斷條件裏的元素,所有的都不是,返回true

System.out.println(stream1.noneMatch(x->x<0)); //返回true

 

 

Short-circuiting :

 

  • 於一個 intermediate 操作,如果它接受的是一個無限大(infinite/unbounded)的 Stream,但返回一個有限的新 Stream。
  • 對於一個 terminal 操作,如果它接受的是一個無限大的 Stream,但能在有限的時間計算出結果。

當操作一個無限大的 Stream,而又希望在有限時間內完成操作,則在管道內擁有一個 short-circuiting 操作是必要非充分條件。

 

anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章