Java學習之路:StreamAPI總結

以下部分內容來自菜鳥教程、文檔Api、馬士兵教育課堂

Java 8 API添加了一個新的抽象稱爲流Stream,可以讓你以一種聲明的方式處理數據。

Stream 使用一種類似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。

Stream API可以極大提高Java程序員的生產力,讓程序員寫出高效率、乾淨、簡潔的代碼。

這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。

元素流在管道中經過中間操作(intermediate operation)的處理,最後由最終操作(terminal operation)得到前面處理的結果。

什麼是 Stream?

Stream(流)是一個來自數據源的元素隊列並支持聚合操作

  • 元素是特定類型的對象,形成一個隊列。 Java中的Stream並不會存儲元素,而是按需計算。
  • 數據源 流的來源。 可以是集合,數組,I/O channel, 產生器generator 等。
  • 聚合操作 類似SQL語句一樣的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作還有兩個基礎的特徵:

  • Pipelining: 中間操作都會返回流對象本身。 這樣多個操作可以串聯成一個管道, 如同流式風格(fluent style)。 這樣做可以對操作進行優化, 比如延遲執行(laziness)和短路( short-circuiting)。
  • 內部迭代: 以前對集合遍歷都是通過Iterator或者For-Each的方式, 顯式的在集合外部進行迭代, 這叫做外部迭代。 Stream提供了內部迭代的方式, 通過訪問者模式(Visitor)實現。

Stream特性

  • 不是數據結構,沒有內部存儲
  • 不支持索引訪問
  • 延遲計算
  • 支持並行
  • 很容易生成數組或者集合(List,Set)
  • 支持過濾,查找,轉換,彙算,聚合等操作。

Stream運行機制

  • stream分爲源source 、中間操作、終止操作。
  • 流的源可以以是一個數組、一個集合、一個生成器方法、一個I/O通道等等。
  • 一個流可以零個和或者多箇中間操作、每一箇中間操作操作都會返回一個新的流、供下一個操作使用、它的源纔開始執行遍歷操作。
  • Stream只有遇到終止操作,它的源纔開始執行遍歷操作。

Stream創建

  • 數組
  • 集合
  • Stream.generate方法來創建
  • Stream.iterate方法來創建
  • 其他API創建

Stream常用API

  • 終止操作
  • 循環forEach
  • 計算min,max,count,average
  • 匹配anyMatch、allMatch、noneMatch、findFirst、findAny
  • 匯聚reduce

收集器toArray、collect

    • Modifier and Type

      Method and Description
      boolean allMatch(Predicate<? super T> predicate)

      返回此流的所有元素是否與提供的謂詞匹配。

      static <T> Stream.Builder<T> builder()

      返回一個 Stream的構建器。

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

      使用 Collector對此流的元素執行 mutable reduction Collector

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

      對此流的元素執行 mutable reduction操作。

      static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

      創建一個懶惰連接的流,其元素是第一個流的所有元素,後跟第二個流的所有元素。

      long count()

      返回此流中的元素數。

      Stream<T> distinct()

      返回由該流的不同元素(根據 Object.equals(Object) )組成的流。

      static <T> Stream<T> empty()

      返回一個空的順序 Stream

      Stream<T> filter(Predicate<? super T> predicate)

      返回由與此給定謂詞匹配的此流的元素組成的流。

      Optional<T> findAny()

      返回描述流的一些元素的Optional如果流爲空,則返回一個空的Optional

      Optional<T> findFirst()

      返回描述此流的第一個元素的Optional如果流爲空,則返回一個空的Optional

      <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

      返回由通過將提供的映射函數應用於每個元素而產生的映射流的內容來替換該流的每個元素的結果的流。

      DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)

      返回一個 DoubleStream ,其中包含將該流的每個元素替換爲通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

      IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper)

      返回一個 IntStream ,其中包含將該流的每個元素替換爲通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

      LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper)

      返回一個 LongStream ,其中包含將該流的每個元素替換爲通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

      void forEach(Consumer<? super T> action)

      對此流的每個元素執行操作。

      void forEachOrdered(Consumer<? super T> action)

      如果流具有定義的遇到順序,則以流的遇到順序對該流的每個元素執行操作。

      static <T> Stream<T> generate(Supplier<T> s)

      返回無限順序無序流,其中每個元素由提供的 Supplier

      static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)

      返回有序無限連續 Stream由函數的迭代應用產生 f至初始元素 seed ,產生 Stream包括 seedf(seed)f(f(seed)) ,等

      Stream<T> limit(long maxSize)

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

      <R> Stream<R> map(Function<? super T,? extends R> mapper)

      返回由給定函數應用於此流的元素的結果組成的流。

      DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)

      返回一個 DoubleStream ,其中包含將給定函數應用於此流的元素的結果。

      IntStream mapToInt(ToIntFunction<? super T> mapper)

      返回一個 IntStream ,其中包含將給定函數應用於此流的元素的結果。

      LongStream mapToLong(ToLongFunction<? super T> mapper)

      返回一個 LongStream ,其中包含將給定函數應用於此流的元素的結果。

      Optional<T> max(Comparator<? super T> comparator)

      根據提供的 Comparator返回此流的最大元素。

      Optional<T> min(Comparator<? super T> comparator)

      根據提供的 Comparator返回此流的最小元素。

      boolean noneMatch(Predicate<? super T> predicate)

      返回此流的元素是否與提供的謂詞匹配。

      static <T> Stream<T> of(T... values)

      返回其元素是指定值的順序排序流。

      Stream<T> peek(Consumer<? super T> action)

      返回由該流的元素組成的流,另外在從生成的流中消耗元素時對每個元素執行提供的操作。

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

      使用 associative累積函數對此流的元素執行 reduction ,並返回描述減小值的 Optional (如果有)。

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

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

      Stream<T> skip(long n)

      在丟棄流的第一個 n元素後,返回由該流的 n元素組成的流。

      Stream<T> sorted()

      返回由此流的元素組成的流,根據自然順序排序。

      Object[] toArray()

      返回一個包含此流的元素的數組。

package com.streams;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream API 方法實踐
 */
public class StreamDemo {
    public static void main(String[] args) {
        System.out.println("輸出集合的值:");
        Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8).stream().filter((x) -> x % 2 == 0).forEach(System.out::println);
        System.out.println("求偶數的和:");
        System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8).stream().filter((x) -> x % 2 == 0).mapToInt((x) -> {
            return x;
        }).sum());
        System.out.println(" Stream.builder():");
        List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);

        Stream.Builder<Object> objectBuilder = Stream.builder().add(asList);
        Stream<Object> build = objectBuilder.build();
        build.forEach(System.out::println);
        System.out.println("求集合最大值:");
        Optional<Integer> optional = asList.stream().max((a, b) -> a - b);
        System.out.println(optional.get());
        System.out.println("求集合的最小值:");
        System.out.println(asList.stream().min((a, b) -> a - b).get());
        System.out.println(asList.stream().filter(x -> x % 2 == 0).findAny().get());
        System.out.println(asList.stream().findFirst().get());
        Stream<Integer> stream = asList.stream().filter(i -> {
            System.out.println("雲心代碼");
            return i % 2 == 0;
        });

        System.out.println(stream.findFirst().get());
        System.out.println("獲取最小和最大值,不使用min和max方法:");
        System.out.println(asList.stream().sorted().findFirst().get());
        System.out.println(asList.stream().sorted().findAny().get());
        System.out.println(asList.stream().sorted((a, b) -> b - a).findFirst().get());
        Arrays.asList("java", "c#", "scala", "python").stream().sorted().forEach(System.out::println);
        Arrays.asList("java", "c#", "scala", "python").stream().sorted((a, b) -> a.length() - b.length()).forEach(System.out::println);
        System.out.println("想將集合的元素進行過濾同時返回一個集合對象:");
        List<Integer> collect = asList.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
        collect.forEach(System.out::println);
        System.out.println("去重操作:");
        System.out.println("使用distinct方法去重:");
        List<Integer> integers = Arrays.asList(1, 2, 3, 3, 4, 5, 6, 7, 7);
        integers.stream().distinct().forEach(System.out::println);
        System.out.println("使用Set集合去重:");
        Set<Integer> set = integers.stream().collect(Collectors.toSet());
        set.forEach(System.out::println);
        System.out.println("//打印20-30這樣的集合元素:");
        Stream<Integer> limit = Stream.iterate(1, x -> x + 1).limit(50).skip(20).limit(10);
        limit.forEach(System.out::println);

        System.out.println("將字符串分割求和:");
        String str = "30,40,50,60,70";
        System.out.println("mapToInt方式一:");
        System.out.println(Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum());
        System.out.println("map+mapToInt方式二:");
        System.out.println(Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());
        System.out.println("mapToInt Integer::valueOf方式三:");
        System.out.println(Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum());
        System.out.println("map Integer::valueOf mapToInt方式四:");
        System.out.println(Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum());

        String str2 = "java,scala,C#,python";
        Stream.of(str2.split(",")).map(x -> new Person(x)).forEach(System.out::println);
        Stream.of(str2.split(",")).map(Person::new).forEach(System.out::println);
        Stream.of(str2.split(",")).map(x -> Person.build(x)).forEach(System.out::println);
        Stream.of(str2.split(",")).map(Person::build).forEach(System.out::println);

        System.out.println("求和並且打印每個元素:");
        System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum());
        System.out.println("比較元素裏面的值是否大於給定的數值:");
        System.out.println(asList.stream().allMatch(x -> x >= 0));
        System.out.println(asList.stream().allMatch(x -> x >= 11));
//        asList.stream().flatMap(x->String.valueOf(x))
    }
}

 

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