Sto scrivendo una libreria per programmatori principianti, quindi sto cercando di mantenere l'API più pulita possibile.Perché il flusso primitivo non è stato raccolto (Collector)?
Una delle cose che la mia biblioteca ha bisogno di fare è eseguire alcuni calcoli complessi su una vasta collezione di interi o long. Ci sono molti scenari e oggetti business di cui i miei utenti hanno bisogno per calcolare questi valori, quindi ho pensato che il modo migliore sarebbe utilizzare gli stream per consentire agli utenti di mappare gli oggetti aziendali su IntStream
o LongStream
e quindi calcolare i calcoli all'interno di un raccoglitore.
Tuttavia IntStream e LongStream hanno solo il parametro 3 metodo di raccogliere:
collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
E non ha la collect(Collector)
metodo più semplice che Stream<T>
ha.
Così, invece di essere in grado di fare
Collection<T> businessObjs = ...
MyResult result = businessObjs.stream()
.mapToInt(...)
.collect(new MyComplexComputation(...));
devo fare fornire Fornitori, accumulatori e combinatori come questo:
MyResult result = businessObjs.stream()
.mapToInt(...)
.collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build(); //prev collect returns Builder object
Questo è troppo complicato per i miei utenti alle prime armi ed è molto incline a errori.
mio lavoro intorno è quello di rendere i metodi statici che accettano un IntStream
o LongStream
come input e nascondono la creazione di raccolta e l'esecuzione per voi
public static MyResult compute(IntStream stream, ...){
return .collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build();
}
Ma che non segue le normali convenzioni di lavoro con Streams:
IntStream tmpStream = businessObjs.stream()
.mapToInt(...);
MyResult result = MyUtil.compute(tmpStream, ...);
Perché bisogna o salvare una variabile temporanea e passare che per il metodo statico, o creare il flusso all'interno della chiamata statica che può essere fonte di confusione quando è è mescolato con gli altri parametri di m computazione
Esiste un modo più semplice per farlo mentre si sta ancora lavorando con IntStream
o LongStream
?
Sfortunatamente, il mio consiglio sarebbe utilizzare 'Stream'. Puoi ottenerlo da 'IntStream' di' mapToObj (Function.identity()) '. –
@DmitryGinzburg il flusso avrà potenzialmente molte migliaia di elementi e il calcolo è piuttosto complesso, non voglio essere penalizzato da tutto il boxing/unboxing – dkatzel
il compilatore potrebbe essere in grado di eliminare il boxing/unboxing se può inline il percorso del codice dalla conversione ai tuoi consumatori. Basta scriverli con le interfacce * int * -based come faresti con 'IntStream' e vedere se genera o meno spazzatura. – the8472