2015-01-07 7 views
7

ich ein Objekt, das wie folgt aussieht folgendeJava 8 Stream-Filterwert von Liste in einer Liste

class MyObject { 

    String type; 
    List<String> subTypes; 

} 

Ist es möglich, eine Liste von MyObject ist gegeben zu verwenden Java 8 Ströme sowohl von der Art zu filtern und dann der Subtyp?

Bisher habe ich

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

aber innerhalb dieses möchte ich auch einen weiteren Filter auf jeder der Subtypen zu denen auf einem bestimmten Subtyp Filterung. Ich kann nicht herausfinden, wie das geht.

Ein Beispiel wäre

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 } ] } 

I in Matchtype B und subType Z passieren würde, so würde ich ein Ergebnis erwarten -> myObject Typ B, Subtypen: W, X, Z

folgenden Gibt zur Zeit 2 Einträge in einer Liste zurück.

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

aber ich möchte ein zusätzliches Filter über die jede der Subtypen hinzuzufügen und nur passende wobei ‚Z‘ vorliegt.

+0

Können Sie ein Beispiel für ein Spiel und ein Miss geben? Müssen * alle * Elemente in 'subTypes' übereinstimmen? –

+0

Möchten Sie 'subTypes' filtern oder was? – kraskevich

+0

Was meinen Sie genau mit "einem anderen Filter auf jedem der SubTypes, der diese auf einem bestimmten Subtyp filtert"? Bitte geben Sie ein Beispiel. –

Antwort

10

können Sie tun:

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

Dies holen all MyObject Objekte, die

  • ein Kriterien in Bezug auf das type Mitglied erfüllen.
  • enthalten Objekte in der verschachtelten List<String>, die einige andere Kriterien erfüllen, vertreten mit <predicate>
+0

anymatch tut es: 3 –

8

sah ich die akzeptierte Antwort von @kocko, die sowohl eine gute Antwort und völlig korrekt. Es gibt jedoch einen leicht alternativen Ansatz, bei dem Sie die Filter einfach verketten.

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

Dies tut im Grunde das Gleiche, aber der && Operand wird zugunsten eines anderen Filter entfernt. Chaining funktioniert sehr gut für die Java 8 Stream API: s und IMO ist es einfacher, den Code zu lesen und zu folgen.

+0

Ich stimme dem letzten Satz zu. Danke –

+0

Irgendein Grund, .stream(). AnyMatch ("Z" :: equals) anstelle von nur .contains ("Z") zu benutzen? Ich bin mir nicht sicher, ob ich etwas verpasse oder ob es tatsächlich dasselbe ist. –

Verwandte Themen