2015-01-07 13 views
7

Ho un un oggetto che assomiglia al seguenteJava 8 flusso valore di filtraggio di lista in una lista

class MyObject { 

    String type; 
    List<String> subTypes; 

} 

E 'possibile, data una lista di MyObject di usare Java 8 flussi di filtrare sia dal tipo e poi il sottotipo?

Finora ho

myObjects.stream() 
    .filter(t -> t.getType().equals(someotherType) 
    .collect(Collections.toList()); 

ma all'interno di questo voglio anche un altro filtro su ciascuna dei sottotipi filtraggio quelli su un particolare sottotipo troppo. Non riesco a capire come farlo.

Un esempio sarebbe

myObject { type: A, subTypes [ { X, Y, Z } ] } 
myObject { type: B, subTypes [ { W, X, Y } ] } 
myObject { type: B, subTypes [ { W, X, Z } ] } 
myObject { type: C, subTypes [ { W, X, Z } ] } 

avrei passare matchtype B e subType Z, in modo che ci si aspetterebbe uno risultato -> tipo myObject B, sottotipi: W, X, Z

seguente attualmente restituisce 2 elementi in una lista.

myObjects.stream() 
    .filter(t -> t.getType().equals("B") 
    .collect(Collections.toList()); 

ma vorrei aggiungere un ulteriore filtro sulla ciascuno dei sottotipi e solo corrispondenza in cui è presente 'Z'.

+0

Puoi fare un esempio di partita e miss? Gli elementi * tutti * in corrispondenza di 'sottotipi 'devono? –

+0

Vuoi filtrare 'sottotipi 'o cosa? – kraskevich

+0

Cosa intendi esattamente per "un altro filtro su ogni sottotipo che filtra quelli su un sottotipo particolare"? Per favore, fai un esempio. –

risposta

10

si può fare:

myObjects.stream() 
     .filter(t -> t.getType().equals(someotherType) && 
         t.getSubTypes().stream().anyMatch(<predicate>)) 
     .collect(Collectors.toList()); 

Verrà recuperato tutti gli oggetti che MyObject

  • incontrare un criterio per quanto riguarda il membro type.
  • contengono oggetti nel nidificato List<String> che soddisfano alcuni altri criteri, rappresentate con <predicate>
+0

anymatch lo fa: 3 –

8

ho visto la risposta accettata dalla @kocko che è sia una buona risposta e totalmente corretta. Tuttavia esiste un approccio leggermente alternativo in cui si concatenano semplicemente i filtri.

final List<MyObject> withBZ = myObjects.stream() 
     .filter(myObj -> myObj.getType().equals("B")) 
     .filter(myObj -> myObj.getSubTypes().stream().anyMatch("Z"::equals)) 
     .collect(Collectors.toList()); 

questo è fondamentalmente facendo la stessa cosa, ma la && operando viene rimosso in favore di un altro filtro. Il concatenamento funziona molto bene per l'API Java 8 Stream: s e IMO è più facile da leggere e seguire il codice.

+0

Sono d'accordo sull'ultima frase. Grazie –

+0

Qualsiasi motivo per usare .stream(). AnyMatch ("Z" :: equals) invece di solo .contains ("Z")? Non sono sicuro se mi manca qualcosa o se sono effettivamente la stessa cosa. –

Problemi correlati