Sto imparando le nuove funzionalità di Java 8 e mentre sperimentavo gli stream (java.util.stream.Stream) e i collezionisti, mi sono reso conto che un flusso non può essere usato due volte. C'è un modo per riutilizzarlo?Esiste un modo per riutilizzare un flusso in java 8?
risposta
Dal documentation:
Un flusso deve essere azionato su (invocare un'operazione flusso intermedia o terminale) solo una volta.
Un'implementazione del flusso può lanciare IllegalStateException se rileva che il flusso viene riutilizzato.
Quindi la risposta è no, i flussi non sono pensati per essere riutilizzati.
L'idea del flusso è che è una volta. Ciò consente di creare origini non rientranti (ad esempio, leggendo le linee dalla connessione di rete) senza memoria intermedia. Se, invece, desidera riutilizzare il contenuto Stream, è possibile scaricare nella collezione intermedia per ottenere il "copia cartacea":
Stream<MyType> stream = // get the stream from somewhere
List<MyType> list = stream.collect(Collectors.toList()); // materialize the stream contents
list.stream().doSomething // create a new stream from the list
list.stream().doSomethingElse // create one more stream from the list
Se non si desidera materializzarsi il torrente, in alcuni casi ci sono modi per fare diverse cose con lo stesso flusso in una volta. Ad esempio, è possibile fare riferimento alla domanda this o this per i dettagli.
Se si desidera avere l'effetto di riutilizzare un flusso, è possibile avvolgere l'espressione di flusso in un fornitore e chiamare myStreamSupplier.get() ogni volta che si desidera uno nuovo. Ad esempio,
Supplier<Stream<String>> sup =() ->
someList.stream();
List<String> nonEmptyStrings = sup.get().filter(s -> !s.isEmpty()).collect(Collectors.toList());
Set<String> uniqueStrings = sup.get().collect(Collectors.toSet());
Come altri hanno detto, "no non si può".
Ma è utile ricordare la portata di mano summaryStatistics()
per molte operazioni di base:
Così, invece di:
List<Person> personList = getPersons();
personList.stream().mapToInt(p -> p.getAge()).average().getAsDouble();
personList.stream().mapToInt(p -> p.getAge()).min().getAsInt();
personList.stream().mapToInt(p -> p.getAge()).max().getAsInt();
È possibile:
// Can also be DoubleSummaryStatistics from mapToDouble()
IntSummaryStatistics stats = personList.stream()
.mapToInt(p-> p.getAge())
.summaryStatistics();
stats.getAverage();
stats.getMin();
stats.getMax();
Sì, i flussi possono essere riutilizzati, solo se nessuno degli usi non chiama alcuna operazione terminale su di esso. –
Possibile duplicato di [Copia un flusso per evitare "il flusso è già stato utilizzato o chiuso" (java 8)] (http://stackoverflow.com/questions/23860533/copy-a-stream-to-avoid-stream- has-already-been-operated-upon-or-closed-java-8) – Andrejs