このようなタスクを処理する最も一般的な方法は、複数のコレクタの結果を1つにまとめることです。 jOOLライブラリを使用して
は、次のものができます。
Content content =
Seq.seq(contentList)
.collect(
Collectors.mapping(Content::getA, Collectors.joining(", ")),
Collectors.mapping(Content::getB, Collectors.joining(", ")),
Collectors.mapping(Content::getC, Collectors.joining(", "))
).map(Content::new);
これは、入力リストからSeq
を作成し、単純に3つの値のためのホルダーである、Tuple3
を作成するために3つの与えられたコレクターを兼ね備えています。これら3つの値は、コンストラクタnew Content(a, b, c)
を使用してContent
にマッピングされます。コレクタ自身は、それぞれContent
をa
,b
またはc
の値にマッピングし、結果を一緒に結合することを", "
で区切ります。
サードパーティの助けがなければ、我々は(これは2人のコレクターのために同じことをStreamExpairing
コレクタの基づいています)、このような当社独自のコンバイナコレクタを作成することができます。引数として3つのコレクターをとり、3つの収集された値の結果に対してフィニッシャー操作を実行します。
public interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}
public static <T, A1, A2, A3, R1, R2, R3, R> Collector<T, ?, R> combining(Collector<? super T, A1, R1> c1, Collector<? super T, A2, R2> c2, Collector<? super T, A3, R3> c3, TriFunction<? super R1, ? super R2, ? super R3, ? extends R> finisher) {
final class Box<A, B, C> {
A a; B b; C c;
Box(A a, B b, C c) {
this.a = a;
this.b = b;
this.c = c;
}
}
EnumSet<Characteristics> c = EnumSet.noneOf(Characteristics.class);
c.addAll(c1.characteristics());
c.retainAll(c2.characteristics());
c.retainAll(c3.characteristics());
c.remove(Characteristics.IDENTITY_FINISH);
return Collector.of(
() -> new Box<>(c1.supplier().get(), c2.supplier().get(), c3.supplier().get()),
(acc, v) -> {
c1.accumulator().accept(acc.a, v);
c2.accumulator().accept(acc.b, v);
c3.accumulator().accept(acc.c, v);
},
(acc1, acc2) -> {
acc1.a = c1.combiner().apply(acc1.a, acc2.a);
acc1.b = c2.combiner().apply(acc1.b, acc2.b);
acc1.c = c3.combiner().apply(acc1.c, acc2.c);
return acc1;
},
acc -> finisher.apply(c1.finisher().apply(acc.a), c2.finisher().apply(acc.b), c3.finisher().apply(acc.c)),
c.toArray(new Characteristics[c.size()])
);
}
し、最終的に
Content content = contentList.stream().collect(combining(
Collectors.mapping(Content::getA, Collectors.joining(", ")),
Collectors.mapping(Content::getB, Collectors.joining(", ")),
Collectors.mapping(Content::getC, Collectors.joining(", ")),
Content::new
));
良い問題の説明とそれを使用しています。しかし今、あなたは何を試しましたか? StackOverflowは他の人にコードを書くことを可能にするコミュニティではありません。むしろ、あなたが試したもの、入手したもの、期待したことを示す[mcve]を投稿する必要があります。また、StackOverflowコミュニティは、あなたが間違っていた場所を特定し、解決策を指摘するのに役立つかもしれません。 – AJNeufeld
@AJNeufeldの提案に感謝します。これは私が毎日それを使用していますが、それについての質問を投稿しようとする初めてのことです。私は、基本的なforループを使って、コンテンツを追加する変数を持っています。そしてストリームのforEachを使用してみたところ、Javaの匿名関数はforeachブロック内の変数を変更できないことに気付きました。また、私は手の届くところに手紙を書こうと思っていたが、効率的ではないと気づいた。 – Vedanth