Il modo più generico per affrontare tali compiti sarebbe quello di combinare il risultato di più collezionisti in uno solo.
Utilizzando la libreria jOOL, si potrebbe avere la seguente:
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);
Questo crea un Seq
dalla lista di input e combina le 3 date collezionisti di creare un Tuple3
, che è semplicemente un supporto per 3 valori. Questi 3 valori vengono quindi mappati in un Content
utilizzando il costruttore new Content(a, b, c)
. Gli stessi collector stanno semplicemente mappando ogni Content
nel suo valore a
, o c
e unendo i risultati insieme separati con uno ", "
.
Senza l'aiuto di terze parti, potremmo creare il nostro collettore combinatore come questo (questo è basato su StreamExpairing
collettore, che fa la stessa cosa per 2 collettori). Prende 3 collector come argomenti ed esegue un'operazione di finisher sul risultato dei 3 valori raccolti.
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()])
);
}
e, infine, lo usano con
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
));
buona descrizione del problema. Ma ora, cosa hai provato? StackOverflow non è una comunità per far sì che altre persone scrivano il codice per te. Piuttosto, devi pubblicare un [mcve] che mostra ciò che hai provato, ciò che hai ottenuto e ciò che ti aspettavi, e la community di StackOverflow potrebbe cercare di aiutare a determinare dove sei andato storto e indicare soluzioni. – AJNeufeld
@AJNeufeld ringrazia per il suggerimento. Questa è anche la prima volta che cerco di pubblicare una domanda su SO anche se la uso tutti i giorni. Ho a che fare con un ciclo di base con una variabile per aggiungere il contenuto. E ho provato ad usare forEach sullo stream e poi ho capito che le funzioni anonimi di Java non consentono la modifica della variabile all'interno del blocco foreach. Inoltre ho pensato di scrivere una raccolta per raggiungerla, ma ho capito che non sarebbe stata neanche efficiente. – Vedanth