Java12 Collectors.teeingあなたが本当にについて知っておく必要があります

序文

それが唯一のコレクターの小さな変化があるので、非常に便利な機能が、JEPの公式発表を持つJava 12、で、その役割は、この文は非常に抽象的と思われる2つのコレクタの結果をマージすることで、古いルール、我々マップを初めて目:

パイプラインの再構築は、多くの場合、その主な役割はdownstream1 downstream2に流入し、マージすることで、その後の合併により流出し、我々は通常、「3個のリンク」と呼んで、この小さなものを使用します。

この画像の説明で、私たちはバーに行きます

Collectors.teeing

上記の機能は、小さなCollectors.teeingのAPI、APIのノートでJDK初見であり、単に無視不快な感じを見て、のような例を下に見て続行します。

/**
 * Returns a {@code Collector} that is a composite of two downstream collectors.
 * Every element passed to the resulting collector is processed by both downstream
 * collectors, then their results are merged using the specified merge function
 * into the final result.
 *
 * <p>The resulting collector functions do the following:
 *
 * <ul>
 * <li>supplier: creates a result container that contains result containers
 * obtained by calling each collector's supplier
 * <li>accumulator: calls each collector's accumulator with its result container
 * and the input element
 * <li>combiner: calls each collector's combiner with two result containers
 * <li>finisher: calls each collector's finisher with its result container,
 * then calls the supplied merger and returns its result.
 * </ul>
 *
 * <p>The resulting collector is {@link Collector.Characteristics#UNORDERED} if both downstream
 * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both downstream
 * collectors are concurrent.
 *
 * @param <T>         the type of the input elements
 * @param <R1>        the result type of the first collector
 * @param <R2>        the result type of the second collector
 * @param <R>         the final result type
 * @param downstream1 the first downstream collector
 * @param downstream2 the second downstream collector
 * @param merger      the function which merges two results into the single one
 * @return a {@code Collector} which aggregates the results of two supplied collectors.
 * @since 12
 */
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) {
    return teeing0(downstream1, downstream2, merger);
}
复制代码

APIの重い文の記述は非常に重要です。

得られた集電体に渡されるすべての要素をされ 、両方の下流コレクターによって処理のことを説明するために関連して「三のリンク地図」、各セットは、処理及びdownstream2のdownstream1う要素の合併を通過します

合併のタイプは、2つのパラメータを受信して​​いるBiFunction、であり、その値を出力し、その適用方法を参照して、前記

@FunctionalInterface
public interface BiFunction<T, U, R> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u);
}
复制代码

あなたが扱うことができる方法のように、我々はそれのいくつかの例を見て

優れた4つの例を挙げて、ティーイングの使用を例示するために、これらの4つの例は、バックAPI上で見に来て、私はあなたが道アウトになると信じて読みます

カウントと蓄積

数の集合与えられた古典的な問題を初めて目には、私たちは、要素とその流れの整数をマップする必要があり、

class CountSum {
	private final Long count;
	private final Integer sum;
	public CountSum(Long count, Integer sum) {
		this.count = count;
		this.sum = sum;
	}

	@Override
	public String toString() {
		return "CountSum{" +
				"count=" + count +
				", sum=" + sum +
				'}';
	}
}
复制代码

Collectors.teeing処理により

CountSum countsum = Stream.of(2, 11, 1, 5, 7, 8, 12)
        .collect(Collectors.teeing(
                counting(),
                summingInt(e -> e),
                CountSum::new));

System.out.println(countsum.toString());
复制代码
  • 静的メソッドコレクターをカウントしてカウントコレクションdownstream1
  • downstream2のコレクション要素の値は、静的メソッドコレクターによって蓄積summingInt
  • 合併の結果収集コンストラクタCountSum

結果:

CountSum {カウント= 7、合計= 46}

私たちは、ダウン他の例を見ていき、ティータイムで私たちが望む結果を得ます:

最大値と最小値

最大値と最小値のセット、新しいクラス同一のMinMaxのセット一度計算によって与えられ、収集結果合併を作成するように構成されています

class MinMax {
	private final Integer min;
	private final Integer max;
	public MinMax(Integer min, Integer max) {
		this.min = min;
		this.max = max;
	}

	@Override
	public String toString() {
		return "MinMax{" +
				"min=" + min +
				", max=" + max +
				'}';
	}
}
复制代码

APIをティー計算結果:

MinMax minmax = Stream.of(2, 11, 1, 5, 7, 8, 12)
        .collect(Collectors.teeing(
                minBy(Comparator.naturalOrder()),
                maxBy(Comparator.naturalOrder()),
                (Optional<Integer> a, Optional<Integer> b) -> new MinMax(a.orElse(Integer.MIN_VALUE), b.orElse(Integer.MAX_VALUE))));

System.out.println(minmax.toString());
复制代码
  • downstream1 minByコレクター静的メソッドは、最小コンパレータコンパレータによって自然順序付けに従って見出されます
  • downstream2 maxByコレクター静的メソッドは、最大値はコンパレータコンパレータによって自然順序付けに従って見出されます
  • 合併の結果はのMinMaxコンストラクタを収集しますが、NPEに対処するために、BiFunctionオプションの処理によって二つのパラメータ

結果:

MinMax {分= 1、最大= 12}

オプションを確認するために、我々は、ヌル要素のセットを追加し、ソート結果を照合外観を変更します:

MinMax minmax = Stream.of(null, 2, 11, 1, 5, 7, 8, 12)
				.collect(Collectors.teeing(
						minBy(Comparator.nullsFirst(Comparator.naturalOrder())),
						maxBy(Comparator.nullsLast(Comparator.naturalOrder())),
						(Optional<Integer> a, Optional<Integer> b) -> new MinMax(a.orElse(Integer.MIN_VALUE), b.orElse(Integer.MAX_VALUE))));
复制代码
  • downstream1処理ルールは、フロントの一種でnullであります
  • downstream2処理ルールは、顔の最後の一種でnullです
  • 合併プロセスは、方法はoptional.orElse、最小および最大出力を実行する場合

結果:

MinMax {分= -2147483648、最大= 2147483647}

メロンや個々の重量の合計重量

次の例について、より実際の操作対象に合わせています

// 定义瓜的类型和重量
class Melon {
	private final String type;
	private final int weight;
	public Melon(String type, int weight) {
		this.type = type;
		this.weight = weight;
	}

	public String getType() {
		return type;
	}

	public int getWeight() {
		return weight;
	}
}

// 总重和单个重量列表
class WeightsAndTotal {
	private final int totalWeight;
	private final List<Integer> weights;
	public WeightsAndTotal(int totalWeight, List<Integer> weights) {
		this.totalWeight = totalWeight;
		this.weights = weights;
	}

	@Override
	public String toString() {
		return "WeightsAndTotal{" +
				"totalWeight=" + totalWeight +
				", weights=" + weights +
				'}';
	}
}
复制代码

そして、重量ティーAPIによって単一のリストの総重量を計算します

List<Melon> melons = Arrays.asList(new Melon("Crenshaw", 1200),
    new Melon("Gac", 3000), new Melon("Hemi", 2600),
    new Melon("Hemi", 1600), new Melon("Gac", 1200),
    new Melon("Apollo", 2600), new Melon("Horned", 1700),
    new Melon("Gac", 3000), new Melon("Hemi", 2600)
);


WeightsAndTotal weightsAndTotal = melons.stream()
    .collect(Collectors.teeing(
            summingInt(Melon::getWeight),
            mapping(m -> m.getWeight(), toList()),
            WeightsAndTotal::new));

System.out.println(weightsAndTotal.toString());
复制代码
  • 累積重量の静的メソッドdownstream1コレクターsummingIntを行います
  • downstream2)(コレクター静的メソッド重量抽出メロンをマッピングし、ToListメソッドストリームの最後の操作結果を取得します
  • 合併取得結果WeightsAndTotalコンストラクタ

結果:

WeightsAndTotal {全重量= 19500、重み= [1200、3000、2600、1600、1200、2600、1700、3000、2600]}

それは、より実用的な共同貼り続けるの例:

人事の予定や予定リストの数

class Guest {
	private String name;
	private boolean participating;
	private Integer participantsNumber;

	public Guest(String name, boolean participating, Integer participantsNumber) {
		this.name = name;
		this.participating = participating;
		this.participantsNumber = participantsNumber;
	}
	public boolean isParticipating() {
		return participating;
	}

	public Integer getParticipantsNumber() {
		return participantsNumber;
	}

	public String getName() {
		return name;
	}
}

class EventParticipation {
	private List<String> guestNameList;
	private Integer totalNumberOfParticipants;

	public EventParticipation(List<String> guestNameList, Integer totalNumberOfParticipants) {
		this.guestNameList = guestNameList;
		this.totalNumberOfParticipants = totalNumberOfParticipants;
	}

	@Override
	public String toString() {
		return "EventParticipation { " +
				"guests = " + guestNameList +
				", total number of participants = " + totalNumberOfParticipants +
				" }";
	}
}
复制代码

APIの処理をすることでティー

var result = Stream.of(
                new Guest("Marco", true, 3),
                new Guest("David", false, 2),
                new Guest("Roger",true, 6))
                .collect(Collectors.teeing(
                        Collectors.filtering(Guest::isParticipating, Collectors.mapping(Guest::getName, Collectors.toList())),
                        Collectors.summingInt(Guest::getParticipantsNumber),
                        EventParticipation::new
                ));
System.out.println(result);
复制代码
  • 最終的にToListメソッドコレクションに自分の名前から人とのマッピングに参加するために特定されフィルタリング方法を介して濾過downstream1、および
  • summingIntを蓄積する方法によりカウントdownstream2
  • 合併の結果収集コンストラクタEventParticipation

我々は結果を収集するために定義Varの結果は、タイプを指定していない、シンタックスシュガーはまた私達のプログラミングの効率をスピードアップ

結果:

EventParticipation {参加のゲスト= [マルコ、ロジャー]、総数= 11}

概要

実際には、ティーイングAPIをdownstream1とdownstream2、最終的にはプロジェクトが同時に収集二つの結果を得るた合併によって収集柔軟なアプリケーションは、要素のコレクションによって処理される静的メソッドコレクター内で定義され、私たちのティーイングAPIを使用する時間です

ソウルの質問

  1. コレクターは、アプリケーション内の静的メソッドは、それを実力?
  2. プロジェクトは、JDKのバージョンを使用しているどのくらいですか?
  3. それをラムダ熟練使用?
  4. その上にあなたのライト?

  1. 更新のための記事のJavaの並行処理シリーズ
  2. Mavenの依存を完全に理解推移
  3. Excelはまた、POIを読むか?このオープンソースのフレームワークを試してみてください
  4. 面接の基本は、常にのようなインタビュアーはなぜJavaのStringを依頼します

簡単な問題、複雑な問題の簡素化と並んで、Javaテクノロジ・スタック関連の知識を学ぶ楽しさを考えて、プログレッシブ技術的な問題の原則の具体的な抽象的でグラフィカルな分解を探偵小説を読むために、技術更新に引き続き、ご期待ください......

おすすめ

転載: juejin.im/post/5dc3956be51d45380d417680