Java8 Stream的使用

一、概述

Stream 關注的是對數據的運算,與CPU打交道;集合關注的是數據的存儲,與內存打交道

  • Stream自己不會存儲數據
  • Stream不會改變源數據,相反,他們會返回一個持有結果的新Stream
  • Stream操作是延遲執行的,這意味着他們會等到需要結果的時候才執行

步驟:

  1. 創建Stream,一個數據源(如:集合,數組),獲取一個流
  2. 中間操作,一箇中間操作鏈,對數據源的數據進行處理
  3. 終止操作,一旦執行終止操作,就執行中間操作鏈,併產生結果,之後,不會再被使用

二、創建Strem

1.通過集合

Java8中的Collection接口有stream,paralleStream方法

  • default Stream<E> stream()              返回一個順序流
  • default Stream<E> paralleStream()   返回一個並行流
@Test
public void test11() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    Stream<Integer> stream = list.stream();
    Stream<Integer> integerStream = list.parallelStream();
}

2.通過數組

 Arrays有靜態方法stream()可以獲取數組流:

  • public static IntStream stream(int[] array)
  • public static LongStream stream(long[] array)
  • public static DoubleStream stream(double[] array)
@Test
public void test12() {
    int[] arr = new int[] {1, 2, 3};
    IntStream intStream = Arrays.stream(arr);
}

3.通過Stream的of()

Stream類有靜態方法of()可以獲取一個流

  • public static<T> Stream<T> of(T... values)
@Test
public void test13() {
    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
}

4.創建無限流

可以使用靜態方法Stream.iterate()和Stream.generate()創建無限流

  • public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
  • public static<T> Stream<T> generate(Supplier<T> s)
@Test
public void test14() {
    Stream<Integer> iterate = Stream.iterate(0, t -> t + 2);
    Stream<Double> generate = Stream.generate(Math::random);
}

三、Stream的中間操作

1.篩選與切片

  • filter(Predicate p)     接受Lambda,從流中篩選某些元素
  • distinct()                   通過流生成元素的hashCode()和equals()去除重複元素
  • limit(long maxSize)  截斷流,使其元素不超過給定數量
  • skip(long n)              跳過元素,返回一個扔掉了前n個元素的流,若流中元素不足n個,則返回一個空流,與limit(n)互補
@Test
public void test21() {
    List<String> list = Arrays.asList("C", "A", "A", "B");
    // 1.filter
    Stream<String> stream = list.stream();
    stream.filter((s) -> s.equals("A")).forEach(System.out::print);
    System.out.println();
    // 2.distinct
    stream = list.stream();
    stream.distinct().forEach(System.out::print);
    System.out.println();
    // 3.limit
    stream = list.stream();
    stream.limit(2).forEach(System.out:: print);
    System.out.println();
    // 4.skip
    stream = list.stream();
    stream.skip(2).forEach(System.out::print);
    System.out.println();
}

結果:

2.映射

  • map(Function f)                                接收一個函數作爲參數,該函數會被應用到每個元素上,並將其映射成一個新的元素
  • mapToDouble(ToDoubleFunction f)  接收一個函數作爲參數,該函數會被應用到每個元素上,產生一個新的DoubleStream
  • mapToInt(ToIntFunction f)                 接收一個函數作爲參數,該函數會被應用到每個元素上,產生一個新的DoubleStream
  • mapToLong(ToLongFunction f)         接收一個函數作爲參數,該函數會被應用到每個元素上,產生一個新的LongStream
  • flatMap(Function f)                            接收一個函數作爲參數,將流中的每個值都換成另一個流,然後把所有流連接成一個流
@Test
public void test22() {
    List<String> list = Arrays.asList("C", "A", "A", "B");
    list.stream().map(str -> str.toLowerCase()).forEach(System.out::print);
}

結果:

3.排序

  • sorted()                            產生一個新流,其中按自然順序排序
  • sorted(Comparator com)  產生一個新流,其中按比較器順序排序
@Test
public void test23() {
    List<String> list = Arrays.asList("C", "A", "A", "B");
    list.stream().sorted().forEach(System.out::print);
}

結果:

四、Stream的終止操作

1.匹配與查找

  •   allMatch(Predicate p)        檢查是否匹配所有元素
  •   anyMatch(Predicate p)      檢查是否至少匹配一個元素
  •   noneMatch(Predicate p)    檢查是否沒有匹配所有元素
  •   findFirst()                           返回第一個元素
  •   findAny()                            返回當前流中的任意元素
  •   count()                               返回流中元素總數
  •   max(Comparator c)           返回流中最大值
  •   min(Comparator c)            返回流中最小值
  •   forEach(Consumer c)        內部迭代(使用Collection接口需要用戶去做迭代,稱爲外部迭代,相反,Stream API使用內部迭代--它幫你把迭代做了)
@Test
public void test31() {
    List<String> list = Arrays.asList("C", "A", "A", "B");
    boolean allMatch = list.stream().allMatch(e -> e.equals("B"));
    System.out.println(allMatch);
    boolean anyMatch = list.stream().anyMatch(e -> e.equals("B"));
    System.out.println(anyMatch);
}

結果:

2.歸約

  • reduce(T iden, BinaryOperator b)    可以將流中元素反覆結合起來,得到一個值,返回T
  • reduce(BinaryOperator b)                可以將流中元素反覆結合起來,得到一個值,返回Optional<T>
@Test
public void test32() {
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    Integer sum = list.stream().reduce(0, Integer::sum);
    System.out.println(sum);
}

結果:

3.收集

Colletor接口中方法的實現決定了如何對流執行收集的操作(如收集到List,Set,Map)

Collectors實用類提供了很多靜態方法,可以方便地創建常見收集器實例

  • collect(Collector c)    將流轉換爲其他形式,接收一個Collector接口的實現,用於給Stream中元素做彙總的方法
@Test
public void test33() {
    List<String> list = Arrays.asList("C", "A", "A", "B");
    List<String> resList = list.stream().filter(e -> e.equals("A")).collect(Collectors.toList());
    System.out.println(resList);
}

結果:

 

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