Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Stream filtering value of list in a list

Tags:

java

java-8

I have a an object which looks like the following

class MyObject {

    String type;
    List<String> subTypes;

}

Is it possible, given a list of MyObject's to use Java 8 streams to filter on both the type and then the subtype?

So far I have

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

but within this I also want another filter on each of the subTypes filtering those on a particular subtype too. I can't figure out how to do this.

An example would be

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 would pass in matchType B and subType Z, so I would expect one result -> myObject type B, subtypes: W, X, Z

the following currently returns 2 items in a list.

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

but I would like to add an additional filter over the each of the subtypes and only matching where 'Z' is present.

like image 369
Simon Kent Avatar asked Jan 07 '15 15:01

Simon Kent


People also ask

How do you filter a list of objects using a Stream?

Java stream provides a method filter() to filter stream elements on the basis of given predicate. Suppose you want to get only even elements of your list then you can do this easily with the help of filter method. This method takes predicate as an argument and returns a stream of consisting of resulted elements.

Does Java Stream filter modify original list?

That means list. stream(). filter(i -> i >= 3); does not change original list. All stream operations are non-interfering (none of them modify the data source), as long as the parameters that you give to them are non-interfering too.


1 Answers

You can do:

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

This will fetch all the MyObject objects which

  • meet a criteria regarding the type member.
  • contain objects in the nested List<String> that meet some other criteria, represented with <predicate>
like image 60
Konstantin Yovkov Avatar answered Oct 15 '22 15:10

Konstantin Yovkov