Java - ティーイングコレクター

こんにちは、未来のJavaの魔法使いたち!? 今日、私たちはJavaのティーイングコレクターのワールドに興味深い旅に出かけます。プログラミングが初めての方でも心配しないでください – 私があなたの友好的なガイドで、一歩一歩進んでいきましょう。このチュートリアルの最後には、Javaでできることに驚きます!

Java - Teeing Collectors

ティーイングコレクターとは?

深いところまで飛び込む前に、まず基本を学びましょう。高級レストランに座って、ウエイターが二つのスポウトを持つティーポットを持ってきたと想像してください。それがJavaのティーイングコレクターのようなものです – データを二つの異なる「カップ」(または操作)に同時に注ぐ方法です!

Javaの言葉で言うと、ティーイングコレクターは同じ入力に対して二つの独立したコレクターを適用し、その結果を組み合わせることができます。それは、同じタスクに取り組む二つのヘルパーが異なる側面に集中し、その後、あなたがその仕事を組み合わせるのと同じです。

Collectors.teeing() メソッド

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:平均と数を計算する

あなたが教師で(私と同じように!)生徒の平均点と生徒の人数を計算したいと思ったら、どのようにティーイングコレクターを使用してこれを行うかを見ていきましょう:

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("平均: %.2f, 人数: %d", average, count)
)
);

System.out.println(result);
}
}

これを分解してみましょう:

  1. 生徒の点数のリストから始めます。
  2. scores.stream()を使用してこれらの点数のストリームを作成します。
  3. Collectors.teeing()を二つのコレクターとともに適用します:
  • Collectors.averagingInt(Integer::intValue)は平均点を計算します。
  • Collectors.counting()は点数の数を数えます。
  1. マージャー関数はこれらの結果をフォーマットされた文字列として組み合わせます。

これを実行すると、以下のような出力が得られます:

平均: 86.60, 人数: 5

素晴らしいでしょうか?わずかなコードで、データから二つの異なるメトリクスを計算できます!

例2:最低点と最高点を見つける

さて、クラスの中で最低点と最高点を同時に見つけたいと思ったらどうでしょう。ティーイングコレクターを使用して、シングルストリーム操作でこれを行うことができます:

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("最低点: %d, 最高点: %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)を使用します。

これを実行すると、以下のような出力が得られます:

最低点: 78, 最高点: 92

なぜティーイングコレクターを使用するのか?

「こんなに大変しなくてもいいのに、なぜこれをするのか?」と思うかもしれませんが、もちろんそれぞれの操作を別々に行うこともできます!しかし、ティーイングコレクターは以下の利点があります:

  1. 効率性: 大きなデータセットに対して一度の反復で済むため、パフォーマンスが大幅に向上します。
  2. 可読性: コードをより簡潔で一目で理解できるようにします。
  3. 柔軟性: 任意の二つのコレクターを創造的に組み合わせて、複雑な問題を解決することができます。

実際の応用

ティーイングコレクターはこれらの簡単な例だけでなく、実際のシナリオでも非常に有用です:

  • 金融アプリケーションでは、一度のパスで取引の合計と平均を計算するために使用します。
  • データ分析では、データセットの中央値と最頻値を同時に見つけるために使用します。
  • ゲーム開発では、最高得点とその得点を達成したプレイヤーの数を追跡するために使用します。

結論

それでは、Javaのティーイングコレクターについて深く掘り下げました。一度に二つの操作を行い、その結果を組み合わせるための単一の効率的なストリーム操作を見ました。

プログラミングは問題解決のことであり、ティーイングコレクターもあなたの問題解決ツールキットの中のもう一つのツールです。これをたくさん練習することで、自分たちのプロジェクトに创造的に使用する方法を見つけることができます。

コーディングを続け、学び続け、そして最も重要なのは楽しむことです!いつかあなたもJavaを教える日が来るかもしれませんし、新しい世代のプログラマーに自分の経験とひどいジョークを共有することができるかもしれません。次回まで、ハッピーコーディング!??‍??‍?

Credits: Image by storyset