1. 程式人生 > >java8 Stream使用案例

java8 Stream使用案例

1. 原理

Stream 不是集合元素,它不是資料結構並不儲存資料,它是有關演算法和計算的,它更像一個高階版本的 Iterator。

原始版本的 Iterator,使用者只能顯式地一個一個遍歷元素並對其執行某些操作;

高階版本的 Stream,使用者只要給出需要對其包含的元素執行什麼操作,比如:

  • 所有元素求和
  • 過濾掉長度大於 10 的字串
  • 獲取每個字串的首字母

Stream 就如同一個迭代器(Iterator),單向,不可往復,資料只能遍歷一次,遍歷過一次後即用盡了,就好比流水從面前流過,一去不復返。

而和迭代器又不同的是,Stream 可以並行化操作

Stream 的另外一大特點是,資料來源本身可以是無限的

2.使用步驟

獲取一個數據源(source)→ 資料轉換→執行操作獲取想要的結果

每次轉換原有 Stream 物件不改變,返回一個新的 Stream物件(可以有多次轉換),這就允許對其操作可以像鏈條一樣排列,變成一個管道,如下圖所示。

3. Stream的構造

 public void test4() {
        Stream stream = Stream.of("a", "b", "c", 23);
        stream.forEach(key -> System.out.println(key));

        String[] array 
= new String[]{"abc", "efg"}; stream = Stream.of(array); stream = Arrays.stream(array); stream.forEach(key -> System.out.println(key)); List<String> list = Arrays.asList(array); stream = list.stream(); //IntStream、LongStream、DoubleStream
IntStream stream2 = IntStream.of(1, 2, 3, 3); DoubleStream stream4 = DoubleStream.of(1, 2, 3, 3.4); stream2.forEach(key -> System.out.println(key)); stream4.forEach(key -> System.out.println(key)); }

結果

a
b
c
23
abc
efg
1
2
3
3
1.0
2.0
3.0
3.4

4. Stream的轉換

public void test6() {
        Stream stream = Stream.of("abc", "def");

        String[] array = (String[])stream.toArray(String[]::new);
        System.out.println(array.length);
        List<String> list = (List<String>)Stream.of("1", "2", "3").collect(Collectors.toList());
        String str = Stream.of("abc", "mn").collect(Collectors.joining()).toString();
        System.out.println(array);
        System.out.println(list);
        System.out.println(str);
    }

結果

2
[Ljava.lang.String;@17f052a3
[1, 2, 3]
abcmn

5.一個 Stream 只可以使用一次

public void test6_5() {
        Stream stream = Stream.of(1, 2, 3, 2);
        System.out.println("count:" + stream.count());
        System.out.println("count:" + stream.count());
} 

輸出

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
	at java.util.stream.LongPipeline.<init>(LongPipeline.java:91)
	at java.util.stream.LongPipeline$StatelessOp.<init>(LongPipeline.java:572)
	at java.util.stream.ReferencePipeline$5.<init>(ReferencePipeline.java:221)
	at java.util.stream.ReferencePipeline.mapToLong(ReferencePipeline.java:220)
	at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)
	at streamTest.StreamTest.test6_5(StreamTest.java:68)
	at streamTest.StreamTest.main(StreamTest.java:181)
count:4

6.轉換大寫

public void test7() {
        List<String> list = Arrays.asList("a", "MnM");

        List<String> result = list.stream().
                map(String::toUpperCase).
                collect(Collectors.toList());
        System.out.println(list);
        System.out.println(result);
    }

輸出

[a, MnM]
[A, MNM]

7.平方

public void test8() {
        List<Integer> list2 = Arrays.asList(1, 2, 4);
        List<Integer> list3 = list2.stream().
                map(key -> key * key).
                collect(Collectors.toList());
        System.out.println(list2);
        System.out.println(list3);

    }

輸出

[1, 2, 4]
[1, 4, 16]

8.找偶數

public void test8_5() {
        List<Integer> list2 = Arrays.asList(1, 2, 4);
        List<Integer> list3 = list2.stream().
                filter(key -> key % 2 == 0).
                collect(Collectors.toList());
        System.out.println(list2);
        System.out.println(list3);
    }

輸出

[1, 2, 4]
[2, 4]

9. 區間值

 public void test5() {
        System.out.println("\n");
        IntStream.range(1, 3).forEach(System.out::println);
        System.out.println("\n");
        IntStream.rangeClosed(1, 3).forEach(System.out::println);
    }

結果

1
2


1
2
3

10.併發

 public void test5_pa() {
        IntStream.rangeClosed(1, 10).parallel().forEach(System.out::println);
    }

輸出

3
7
1
5
2
8
10
6
9
4  

11. 新的Stream繼續操作

public void test6_6() {
        Stream.of("one", "two", "three", "four")
                .filter(e -> e.length() > 3)
                .peek(e -> System.out.println("Filtered value: " + e))
                .map(String::toUpperCase)
                .peek(e -> System.out.println("Mapped value: " + e))
                .collect(Collectors.toList());
    }

結果

Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR

12. Optional

public static void print(String text) {
        System.out.println("<<<<<<");
        System.out.println(Optional.ofNullable(text));
        List<String> obj = new ArrayList<>();
        Optional.ofNullable(text).ifPresent(System.out::println);
        System.out.println(">>>>>>>>>>>>\n");
    }
    public static int getLength(String text) {
        return Optional.ofNullable(text).map(String::length).orElse(-1);
    }

    public void test14() {
        String strA = " abcd ", strB = null;
        print(strA);
        print("");
        print(strB);

        System.out.println(getLength(strA));
        System.out.println(getLength(""));
        System.out.println(getLength(strB));
    }

結果

<<<<<<
Optional[ abcd ]
 abcd 
>>>>>>>>>>>>

<<<<<<
Optional[]

>>>>>>>>>>>>

<<<<<<
Optional.empty
>>>>>>>>>>>>

6
0
-1

13. 字串拼接、最值、求和、過濾

public void test15() {
        String concat = Stream.of("A", "B", "C").reduce("", String::concat);
        System.out.println("concat:" + concat);

        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
        System.out.println("min:" + minValue);

        int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
        System.out.println("sum1:" + sumValue);

        int sumValue2 = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
        System.out.println("sum2:" + sumValue2);

        concat = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat);
        System.out.println("concat:" + concat);
    }

結果

concat:ABC
min:-3.0
sum1:10
sum2:10
concat:ace

14. limit, skip

public void test16() {
        List<Person> persons = new ArrayList<>();
        IntStream.range(1, 1000).forEach(key->persons.add(new Person(key, "jihite:" + key)));
        List<String> personList = persons.stream().map(Person::getName).limit(10).skip(3).collect(Collectors.toList());
        System.out.println(personList);
    }

輸出

[jihite:4, jihite:5, jihite:6, jihite:7, jihite:8, jihite:9, jihite:10]

15.找出最長一行的長度

public void test19() throws IOException {
        String path = "**/Person.java";
        BufferedReader br = new BufferedReader(new FileReader(path));
        int longest = br.lines()
                .mapToInt(String::length)
                .max()
                .getAsInt();
        br.close();
        System.out.println(longest);
    }

輸出

40

16.找出全文的單詞,轉小寫,並排序

public void test20() throws IOException {
        String path = "**/Person.java";
        BufferedReader br = new BufferedReader(new FileReader(path));
        List<String> words = br.lines()
                .flatMap(line->Stream.of(line.split(" ")))
                .filter(word->word.length()>0)
                .map(String::toLowerCase)
                .distinct()
                .sorted()
                .collect(Collectors.toList());
        br.close();
        System.out.println(words);
        words.forEach(key-> System.out.println(key));
    }

輸出

*
*/
/**
//
2018/10/24
21:40
=
@author:
@date:
@description:
class
getname()
int
name)

參考