Se si dispone di scenario più complesso o non piace @Aaron rispondere per qualche motivo, si può fare il trucco flatMap-cattura la creazione di flusso di un elemento per ogni elemento esterno:
as.stream().
flatMap(a -> Stream.of(a.getX()).
filter(x -> x != null).
map(x -> a)).
forEach(System.out::println);
Qui abbiamo flusso nidificato per elemento in cui è possibile eseguire operazioni di flusso senza stato (map
, filter
, peek
e flatMap
) con riferimento all'elemento originale. Dopo che l'elemento originale non è più necessario, chiudi lo flatMap
e prosegui con lo stream originale. Esempio:
Stream.of("a", "bb", "ccc", "dd", "eeee")
.flatMap(a -> Stream.of(a.length())
.filter(x -> x > 2)
.map(x -> a))
.forEach(System.out::println);
// prints "ccc" and "eeee".
O due filtri:
Stream.of("a", "bb", "ccc", "dd", "eeee")
.flatMap(a -> Stream.of(a.length())
.filter(x -> x > 2)
.map(x -> a.charAt(0)) // forget the length, now check the first symbol
.filter(ch -> ch == 'c')
.map(x -> a)) // forget the first symbol, reverting to the whole string
.forEach(System.out::println);
// prints only "ccc"
Naturalmente tali scenari semplici potrebbero essere riscritte come suggerisce @Aaron, ma nei casi più complessi flatMap-cattura può essere soluzione adeguata.
fonte
2016-05-19 05:34:16
Se la ricerca è associata a 'x ', suggerirei piuttosto di cambiare il codice per ottenere qualcosa come' a.lookup (lookup: get) '. Allora avresti un semplice 'forEach'. – zeroflagL
'for (A a: as) if (a.getX()! = Null) a.setLookedUpVal (lookup.get (a.getX()));' oppure, se 'getX()' è costoso, 'per (A a: as) {X x = a.getX(); if (x! = null) a.setLookedUpVal (lookup.get (x)); } '. Confronta ogni soluzione basata su Stream con * that * prima di decidere di usarlo ... – Holger