Java 8 Streams用法與範例

2019/08/31 Java

參考來源

Streams是啥?

Streams從Java 8開始支援,新的Java 8藉由Streams把函數式編程(Functional Programming)帶入了Java編程中。(什麼是函數式編程?)

Stream有甚麼好處?

  • 讓Java編程更有效率
  • 使用大量的lambda expression(匿名函數)
  • ParallelStreams的api讓多執行緒的操作更加容易了

Streams的組成

  • Stream來源(Stream Source) Streams的來源可以是Collections, Lists, Sets, ints, longs, doubles, arrays, lines of file

  • Stream的操作可以是中間操作(intermediate operation)或是終端操作(terminal operation)

    • 中間操作 (intermediate operation): 例如filter、map、sort等函數會回傳stream,所以可以把它們串連起來操作。
    • 終端操作 (terminal operation): 像是forEach、collect、reduce等函數會回傳void或是其他不是stream的結果,所以操作到這邊就會中斷。

中間操作 (intermediate operation)

可以容許0個以上的中介操作,排列順序會影響執行的順序,例如如果在比較大的資料上面做操作的話,先filter再sort或map效能會比較好一點(減少後面函數要處理的資料量)

較大的資料量也可以用ParallelStream來使用多執行緒來操作。

中間操作有:

anyMatch()
distinct()
filter()
findFirst()
flatmap()
map()
skip()
sorted()

終端操作 (terminal operation)

只能有一個終端操作!

  • forEach對所有元素執行同一個方法
  • collect將所有元素放入一個集合(Collection)裡
  • 其他方法只回傳一個元素,像是:
count()
max()
min()
reduce()
summayStatistics()

範例 Examples

1. 印出整數列 Integer Stream

IntStream
    .range(1, 10)
    .forEach(System.out::print); // java裡的方法引用! 類名::方法名
System.out.println();

Output:

123456789

2. 印出整數列,跳過前幾個元素

IntStream
    .range(1, 10)
    .skip(5) // 跳過頭5個元素
    .forEach(x -> System.out.println(x)); // 匿名函數
System.out.println();

Output:

6
7
8
9

3. 印出整數列的和

System.out.println(
    IntStream
    .range(1, 5)
    .sum());
System.out.println();
)

Output:

10

4. Stream.of用法

Stream.of("Ava", "Aneri", "Alberto") // 將一連串的資料變成collection的stream
    .sorted() // 排序
    .findFirst() // 抓出第一個資料
    .ifPresent(System.out::println); //如果有資料的話印出來

Output:

Alberto

5. 過濾陣列裡的資料

找出所有S開頭的名字

String[] names = {"Al", "Ankit", "Kushal", "Brent", "Sarika", "amanda", "Hans", "Shivika"};
Arrays.stream(names) // same as Stream.of(names)
    .filter(x -> x.startsWith("S"))
    .sorted()
    .forEach(System.out::println());

Output:

Sarika
Shivika

6. map()用法

計算整數陣列所有元素平方的平均

Arrays.stream(new int[] {2, 4, 6, 8, 10})
    .map(x -> x * x)
    .average() // 求出平均
    .ifPresent(System.out::println);

Output:

44.0 // 印出double而不是int!!

7. 結合map()及filter()

List<String> people = Arrays.asList("Al", "Ankit", "Kushal", "Brent", "Sarika", "amanda", "Hans", "Shivika");
people
    .stream()
    .map(String::toLowerCase)
    .filter(x -> x.startsWith("a"))
    .forEach(System.out::println);

Output:

al
ankit
amanda

8. 文字檔處理

Stream<String> bands = Files.lines(Paths.get("bands.txt"));
bands
    .sorted()
    .filter(x -> x.length() > 13);
    .forEach(System.out::println);
bands.close();

9. reduce()用法

將陣列裡所有數相加

double total = Stream.of(7.3, 1.5, 4.8);
    .reduce(0.0, (Double a, Double b) -> a + b); // 0.0是起始點
System.out.println("Total = " + total);

10. summaryStatistics()用法

IntSummaryStatistics summary = IntStream.of(7, 2, 19, 88, 73, 4, 10)
    .summaryStatistics();
System.out.println(summary);

Output:

IntSummaryStatistics{count=7, sum=203, min=2, average=29.000000, max=88}

Search

    Table of Contents