iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
Software Development

Java 17 新登場系列 第 5

Day 5 - 串流操作 2

  • 分享至 

  • xImage
  •  

使用 peek 來除錯串流

在不干擾串流的情況下,對串流執行動作,並回傳串流
正確的使用方式不能修改到串流,而且在正式版程式碼裡面不應該存在
剛好拿來 debug 串流,下面的例子也展示了流式處理的特性

# 基本使用
List<Integer> intList = Stream.of(1, 2, 3)
                              .peek(e -> System.out.println(String.valueOf(e)))
                              .collect(Collectors.toList());

# 可以使用任意多 peek
# peek 流式處理,每一個元素"按順序"流過並輸出
IntStream.rangeClosed(start, end)
                        .peek(n -> System.out.printf("original: %d%n", n))
                        .map(n -> n * 2)
                        .peek(n -> System.out.printf("doubled : %d%n", n))
                        .filter(n -> n % 3 == 0)
                        .peek(n -> System.out.printf("filtered: %d%n", n))
                        .sum();
// output: 
original:100
doubled:200
original:101
doubled:202
original:102
doubled:204
.......

將字串轉換成串流,也轉換回去

String 不屬於 Collections 框架,沒有實作 Iterable 所以 沒辦法使用 Stream 的工廠方法產生 Stream
不過 String 實作了 CharSequence 介面,這個介面有兩個方法可以產生 IntStream:

default IntStream chars() //回傳 char 值構成的 IntStream
default IntStream codePoints() //回傳 Unicode 字碼指標的 IntStream

另外,我們也需要將字元串流轉回 String,可惜的是,collect 聚合支援的 Collectors 並沒有適合的方法可以用,collect 有兩個多載版本

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

//過濾掉數字 & 空白
String str = "2023 ithome 鐵人賽 ";
String result = str.codePoints()
        .filter(n ->  !Character.isDigit((char)n) &&   !Character.isWhitespace((char)n))
        .collect(StringBuilder::new, 
									StringBuilder::appendCodePoint, 
									StringBuilder::append).toString();
System.out.println(result);
//output: ithome鐵人賽

計算元素數量

呼叫 Stream 的方法 count() 得到串流元素的數量 (long)

long count = Stream.of(3,2,2,3,4,5,4,3,2,1).count();
System.out.println(count);
//output: 10

摘要統計

互叫 IntStream、DoubleStream、LongStream 的 sunmmaryStatistics 方法

DoubleSummaryStatistics stats = DoubleStream.generate(Math::random)
                .limit(1_000_000)
                .summaryStatistics();

System.out.println(stats);

System.out.println("count: " + stats.getCount());
System.out.println("min  : " + stats.getMin());
System.out.println("max  : " + stats.getMax());
System.out.println("sum  : " + stats.getSum());
System.out.println("ave  : " + stats.getAverage());

尋找串流的第一個元素

//找出第一個大於 10 的偶數
Optional<Integer> firstEvenGT10 = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5)
                .filter(n -> n > 10)
                .filter(n -> n % 2 == 0)
                .findFirst();

System.out.println(firstEvenGT10);
//output: Optional.empty

參考資料:

https://nicksamoylov.medium.com/java-streams-11-create-from-string-using-chars-codepoints-and-lines-953f85d5d7ec
https://www.digitalocean.com/community/tutorials/java-stream-collect-method-examples
現代 Java - 輕鬆解決 Java 8 & 9 的難題(O'REILLY)


上一篇
Day 4 - 串流操作 1
下一篇
Day 6 - 串流操作 3
系列文
Java 17 新登場8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言