Il Java documentazioni API afferma che il parametro combiner
del metodo collect
deve essere:Dove è definito l'ordine di combinazione del combinatore di raccolta (fornitore, accumulatore, combinatore)?
associativo, non interferente, funzione stateless per combinare due valori, che devono essere compatibili con la funzione di accumulatore
A combiner
è un BiConsumer<R,R>
che riceve due parametri di tipo R
e restituisce void
. Ma la documentazione non dice se dovremmo combinare gli elementi nel primo o nel secondo parametro?
Ad esempio i seguenti esempi possono dare risultati diversi, a seconda dell'ordine di combinazione: m1.addAll(m2)
o m2.addAll(m1)
.
List<String> res = LongStream
.rangeClosed(1, 1_000_000)
.parallel()
.mapToObj(n -> "" + n)
.collect(ArrayList::new, ArrayList::add,(m1, m2) -> m1.addAll(m2));
So che in questo caso si potrebbe usare semplicemente un manico metodo, ad esempio ArrayList::addAll
. Tuttavia, ci sono alcuni casi in cui è richiesto un Lambda e dobbiamo combinare gli articoli nell'ordine corretto, altrimenti potremmo ottenere un risultato incoerente durante l'elaborazione in parallelo.
Questo è affermato in qualsiasi parte della documentazione dell'API Java 8? O davvero non importa?
Hai ragione, il javadoc non è scritto molto chiaramente - confusamente, dice che il combinatore deve essere associativo !. Probabilmente è un residuo di una versione precedente, che utilizzava un 'BinaryOperator' piuttosto che un' BiConsumer'. Ma dagli esempi forniti è chiaro che il combinatore deve accumularsi nel suo primo argomento. – Misha