使用多个过滤器的Java Stream搜索列表

Dre*_*w13 5 java java-stream

我有一个Java对象列表(假设getter和setter):

Record(String name, String part, String value);
Run Code Online (Sandbox Code Playgroud)

如果列表包含某个name值和某个值,我需要返回一个布尔part值.

我让它一次为一个过滤器工作:

//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();
Run Code Online (Sandbox Code Playgroud)

但我得到的错误Non-static method cannot be referenced from a static contextRecord::getPart此尝试:

masterList.stream().map(Record::getName).filter(record.getName()::equals).map(Record::getPart).filter(record.getPart()::equals).findFirst().isPresent();
Run Code Online (Sandbox Code Playgroud)

Ous*_* D. 4

您尝试做的事情是不可能的,即当您执行时,所有字符串map(Record::getName)都是Stream<String>记录名称,并且此后的任何链接方法调用仅基于记录名称。

相反,只使用一个filter

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

或更好地使用anyMatch

boolean check = masterList.stream()
                         .anyMatch(s -> s.getName().equals(record.getName()) &&
                                    s.getPart().equals(record.getPart()));
Run Code Online (Sandbox Code Playgroud)

编辑:

是否可以是一条记录匹配名称,另一条记录匹配部分?

然后您可以将所有记录名称和部分收集到一个集合中,如下所示:

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

然后做:

boolean result = container.contains(record.getName()) && 
                 container.contains(record.getPart()) ;
Run Code Online (Sandbox Code Playgroud)

  • @shmosel 至于“如果名称和部分相同,第二个解决方案可能会失败。” _如果这是他们设计中的一种可能情况_那么可以选择 --&gt; `masterList.stream().anyMatch(s -&gt; s.getName().equals(record.getName())) &amp;&amp; masterList.stream() .anyMatch(s -&gt; s.getPart().equals(record.getPart()));` (2认同)