2016-02-09 11 views
10

Dato un Map mappatura di una stringa su List, c'è un modo per utilizzare Java Streams per restituire un booleano dove TRUE indica uno o più elenchi aveva elementi? Se tutti gli elenchi nella mappa erano vuoti, restituire FALSE.Usa flussi per restituire booleano se tutti i valori Elenco in una mappa sono vuoti/non vuoti

Map< String , List<String> > map = … 

L'uso di stream può sostituire questo codice convenzionale?

// See if any diffs were found. Loop through the Map, look at each List of diffs to see if non-empty. 
boolean anyElementsInAnyList = false; 
for (List<String> list : map.values()) { 
    if (!list.isEmpty()) { 
     anyElementsInAnyList = true; 
     break; 
    } 
} 

Si noti che è possibile uscire dall'esame dopo il primo rilevamento. Non è necessario esaminare tutti i valori della mappa (tutti gli elenchi). Sarebbe bello se, per efficienza, lo Stream potesse fare lo stesso stop-work-on-first-finding (un'operazione di "cortocircuito").

+1

Intendi questo flusso java? http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html –

+0

Qualche motivo per usare 'Boolean' invece di' boolean' nel tuo loop? – Holger

risposta

14

In Java 8 è possibile verificare che non tutti gli elenchi siano vuoti.

boolean anyNonEmpty = !map.values().stream().allMatch(List::isEmpty); 
+1

È interessante vedere il contrario del codice in [risposta di rgettman] (http://stackoverflow.com/a/35282464/642706), utilizzando 'allMatch' contro' anyMatch'. Mi sembra che questo approccio qui non possa avvantaggiarsi di un'operazione di "cortocircuito". Quindi non è efficiente come quello di rgettman che andrà in corto circuito. –

+5

@BasilBourque Anche il metodo 'allMatch' è in cortocircuito. – rgettman

+2

@Basil Bourque: non seguire il nome del metodo, passare [la documentazione] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#allMatch -java.util.function.Predicate-): "* Si tratta di un'operazione del terminale di cortocircuito. *" – Holger

7

Utilizzare the anyMatch method che trova se un elemento dello stream corrisponde a Predicate. Qui, il tuo predicato è che il valore della voce (la lista) non è vuoto.

boolean anyNonEmpty = map.entrySet() 
    .stream() 
    .anyMatch(entry -> !entry.getValue().isEmpty()); 
+0

@hotkey Dovresti aver appena commentato che potrei sostituire 'entrySet' con' values' e nel predicato andare direttamente a '! List.isEmpty'. – rgettman

+0

Bene, grazie! Il documento dice che questo metodo è un [operazione terminale di cortocircuito] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps). Quindi questo stream dovrebbe avere un po 'dell'efficienza di non controllare tutti i valori nella mappa. Apparentemente otteniamo questo beneficio anche lavorando in parallelo (multi-thread) secondo [questa domanda] (http://stackoverflow.com/q/27235839/642706). –

+0

@rgettman, OK, mi dispiace. – hotkey

0
int size = Map.entrySet().stream() 
          .map(entry -> entry.getValue()) 
          .flatMap(list -> list.stream()) 
          .size(); 
if(size==0) 
    return Boolean.False; 
else 
    return Boolean.True; 

Questo codice è semplice questo può aiutare per il vostro lavoro.

+1

Down-votes? Per favore lasciate i vostri commenti critici insieme al vostro voto. Questa è una risposta solida, educativa, con un interessante approccio alternativo. Non è la soluzione migliore per lo scenario di questa domanda, ma potrebbe essere abbastanza utile per altri lettori con uno scenario leggermente diverso. –

+2

Non ho fatto un downvote, ma ci sono alcune cose ovvie da criticare. Innanzitutto, l'uso di 'Map' (facile da confondere con il tipo di quel nome) al posto della variabile corretta' map', quindi, non ha senso scorrere su 'entrySet()' solo per mappare i valori in il prossimo passo, soprattutto perché la domanda già allude all'esistenza di 'values ​​()' che puoi trasmettere in streaming in primo luogo. Inoltre, non esiste un metodo 'size()' in 'Stream' e anche se esistesse, era uno spreco di risorse qui, in quanto il conteggio di tutti gli elementi non può essere in cortocircuito in generale. Per non parlare di 'return size == 0;' ... – Holger

Problemi correlati