Search list with Java Stream using multiple filters

Viewed 2242

I have a List of Java Objects (assume getters and setters):

Record(String name, String part, String value);

I need to return a boolean for if the list contains a certain name value and a certain part value.

I have it working for one filter at a time:

//assume records are added to this list
List<Record> masterList = new ArrayList<Record>();

boolean check = masterList.stream().map(Record::getName).filter(record.getName()::equals).findFirst().isPresent();

But I get error Non-static method cannot be referenced from a static context on Record::getPart for this attempt:

masterList.stream().map(Record::getName).filter(record.getName()::equals).map(Record::getPart).filter(record.getPart()::equals).findFirst().isPresent();
1 Answers

What you're attempting to do is just not possible i.e. when you perform map(Record::getName) you have a Stream<String> where all the strings are the record names and any chained method calls after that is based only upon the record names.

instead just use a single filter:

boolean check = masterList.stream()
                           .filter(s -> s.getName().equals(record.getName()) &&
                                        s.getPart().equals(record.getPart()))
                           .findFirst().isPresent();

or better use anyMatch

boolean check = masterList.stream()
                         .anyMatch(s -> s.getName().equals(record.getName()) &&
                                    s.getPart().equals(record.getPart()));

Edit:

if it can be one record matching name, and another record matching part?

Then you can collect all the record names and parts into a set as follows:

Set<String> container = masterList.stream()
                                  .flatMap(r -> Stream.of(r.getName(), r.getPart()))
                                  .collect(toSet());

Then do:

boolean result = container.contains(record.getName()) && 
                 container.contains(record.getPart()) ;
Related