Flussi
Prima di Java 8
for (Direction dir : Direction.values()) {
System.out.println(dir);
}
Java 8
Possiamo anche utilizzare lambda e stream ( Tutorial ):
Stream.of(Direction.values()).forEachOrdered(System.out::println);
Perché forEachOrdered
e non forEach
con i flussi?
Il comportamento di forEach
è esplicitamente non deterministico dove come forEachOrdered
esegue un'azione per ciascun elemento di questo flusso, nell'ordine di incontro del flusso se il flusso ha un ordine di incontro definito. Quindi forEach
non garantisce che l'ordine verrà mantenuto.
Inoltre, quando si lavora con flussi (in particolare quelli paralleli), tenere presente la natura dei flussi. Secondo il documento :
I risultati della pipeline del flusso possono essere non deterministici o errati se i parametri comportamentali per le operazioni del flusso sono stateful. Un lambda con stato è uno il cui risultato dipende da qualsiasi stato che potrebbe cambiare durante l'esecuzione della pipeline del flusso.
Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
In questo caso, se l'operazione di mappatura viene eseguita in parallelo, i risultati per lo stesso input potrebbero variare da un'esecuzione all'altra, a causa delle differenze di pianificazione del thread, mentre, con un'espressione lambda senza stato, i risultati sarebbero sempre gli stessi.
Gli effetti collaterali nei parametri comportamentali per le operazioni di streaming sono, in generale, scoraggiati, poiché spesso possono portare a involontarie violazioni del requisito di apolidia, nonché ad altri pericoli per la sicurezza dei thread.
Gli stream possono avere o meno un ordine di incontro definito. Il fatto che uno stream abbia o meno un ordine di incontro dipende dalla sorgente e dalle operazioni intermedie.