Java - Teeing Collectors

你好啊,未來的Java巫師们!? 今天,我們將進入Java的Teeing Collectors的精彩世界。如果你是編程新手,不用擔心——我會成為你友善的導遊,我們將一步步來學習。在這篇教程結束時,你將對Java能做的事情感到驚訝!

Java - Teeing Collectors

Teeing Collectors是什麼?

在我們深入探究之前,先從基礎開始。想像你在一個高級餐廳,服務員給你帶來一個雙嘴茶壺。這就是Java中的Teeing Collector——一種將你的數據同時倒入兩個不同的“杯子”(或操作)的方法!

在Java的語境中,Teeing Collector允許你 對同一個輸入應用兩個獨立的收集器,然後再合併它們的結果。這就像是有兩個助手在處理同一個任務,但專注於不同的方面,然後你將他們的工作在結束時合併。

Collectors.teeing() 方法

Java在Java 12中引入了Collectors.teeing()方法。它是Stream API的一部分,這是一個用於處理數據集的強大工具。讓我們來解析它的語法:

語法

public static <T,R1,R2,R> Collector<T,?,R> teeing(
Collector<? super T,?,R1> downstream1,
Collector<? super T,?,R2> downstream2,
BiFunction<? super R1,? super R2,R> merger)

別讓這個看起來令人生畏的語法把你嚇住了!讓我們來解析一下:

  • T:輸入元素的類型
  • R1:第一個收集器的結果類型
  • R2:第二個收集器的結果類型
  • R:最終結果的類型

該方法接受三個參數:

  1. downstream1:第一個收集器
  2. downstream2:第二個收集器
  3. merger:一個函數,用於合併兩個收集器的結果

現在,讓我們通過一些例子來看看它的實際操作!

示例1:計算平均值和計數

想像你是一名老師(就像我一樣!)並且你想計算學生的平均分數以及你有多少學生。以下是使用Teeing Collector來完成這項任務的方法:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StudentScoreAnalyzer {
public static void main(String[] args) {
List<Integer> scores = Arrays.asList(85, 90, 78, 92, 88);

var result = scores.stream().collect(
Collectors.teeing(
Collectors.averagingInt(Integer::intValue),
Collectors.counting(),
(average, count) -> String.format("Average: %.2f, Count: %d", average, count)
)
);

System.out.println(result);
}
}

讓我們來解析一下:

  1. 我們從一個學生分數的列表開始。
  2. 我們使用scores.stream()來創建這些分數的流。
  3. 我們應用Collectors.teeing()和兩個收集器:
  • Collectors.averagingInt(Integer::intValue)計算平均分數。
  • Collectors.counting()計算分數的數量。
  1. 合併函數將這些結果合並為格式化的字符串。

當你運行這個程序時,你將看到如下輸出:

Average: 86.60, Count: 5

這不是很棒嗎?只用幾行代碼,我們就從我們的數據中計算出了兩個不同的指標!

示例2:尋找最低和最高分數

現在,讓我們說你想找到你班級中的最低和最高分數。我們可以使用單個流操作和Teeing Collector來完成這項工作:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StudentScoreAnalyzer {
public static void main(String[] args) {
List<Integer> scores = Arrays.asList(85, 90, 78, 92, 88);

var result = scores.stream().collect(
Collectors.teeing(
Collectors.minBy(Integer::compareTo),
Collectors.maxBy(Integer::compareTo),
(min, max) -> String.format("Lowest: %d, Highest: %d", min.orElse(0), max.orElse(0))
)
);

System.out.println(result);
}
}

在這個例子中:

  1. 我們使用同一個分數列表。
  2. 我們的第一個收集器Collectors.minBy(Integer::compareTo)找到最低分數。
  3. 我們的第二個收集器Collectors.maxBy(Integer::compareTo)找到最高分數。
  4. 合併函數將這些合並為格式化的字符串,使用orElse(0)來處理列表可能為空的情況。

運行這個程序將會給你:

Lowest: 78, Highest: 92

為什麼使用Teeing Collectors?

你可能会想,“為什麼要麻煩這麼做?我們不能分別進行這些操作嗎?”當然可以!但是Teeing Collectors提供了一些優勢:

  1. 效率:你只需要遍歷數據一次,對於大型數據集來說,這可能是一個很大的性能提升。
  2. 可讀性:它使你的代碼更簡潔,一眼就能看懂。
  3. 靈活性:你可以以創意的方式結合任何兩個收集器來解決複雜的問題。

實際應用

Teeing Collectors不僅適用於這些簡單的例子。它在真實世界的情境中可能非常有用:

  • 在金融應用中,你可能會用它們來在一次通過中計算交易的总和和平均值。
  • 在數據分析中,你可以用它們同時找到數據集的中位數和众數。
  • 在遊戲開發中,你可以跟蹤最高分數和達成該分數的玩家數量。

結論

就是這樣,各位!我們已經深入探讨了Java的Teeing Collectors的世界。我們看到了它們如何幫助我們一次執行兩個操作並合併結果,所有這些都在一個單一的、有效的流操作中完成。

記住,編程就是解決問題,而Teeing Collectors只是你解決問題工具箱中的另一個工具。你練習得越多,你會發現越多的創意方式在你的項目中使用它們。

繼續編碼,繼續學習,最重要的是,玩得開心!誰知道呢?也許有一天你會教Java,與新一代的程序員分享你的經驗和糟糕的笑話。直到下次,編程愉快!??‍??‍?

Credits: Image by storyset