java - 如何在 Java Stream 上应用多个过滤器?
问题描述
我必须通过映射过滤对象集合,其中包含对象字段名称和字段值的键值对。我正在尝试通过 stream().filter() 应用所有过滤器。
对象实际上是 JSON,因此 Map 包含其变量的名称以及它们必须包含的值才能被接受,但为了简单起见,因为它与问题无关,我编写了一个简单的 Testclass 来模拟行为:
public class TestObject {
private int property1;
private int property2;
private int property3;
public TestObject(int property1, int property2, int property3) {
this.property1 = property1;
this.property2 = property2;
this.property3 = property3;
}
public int getProperty(int key) {
switch(key) {
case 1: return property1;
case 2: return property2;
default: return property3;
}
}
}
到目前为止我已经尝试过:
public static void main(String[] args) {
List<TestObject> list = new ArrayList<>();
Map<Integer, Integer> filterMap = new HashMap<>();
list.add(new TestObject(1, 2, 3));
list.add(new TestObject(1, 2, 4));
list.add(new TestObject(1, 4, 3));
filterMap.put(3, 3); //Filter property3 == 3
filterMap.put(2, 2); //Filter property2 == 2
//Does not apply the result
filterMap.forEach((key, value) -> list.stream()
.filter(testObject -> testObject.getProperty(key) == value)
.collect(Collectors.toList())
);
/* Gives error: boolean can not be converted to void
list = list.stream()
.filter(testObject -> filterMap.forEach((key, value) -> testObject.getProperty(key) == value))
.collect(Collectors.toList()
);
*/
//Printing result
list.forEach(obj -> System.out.println(obj.getProperty(1) + " " + obj.getProperty(2) + " " + obj.getProperty(3)));
}
我尝试首先放置 Map 的 forEach 和 Collection 的流,但两种解决方案都没有按预期工作。此示例的所需输出将仅打印具有值 property1=1、property2=2 和 property3=3 的对象。
如何正确应用所有过滤器,就像您将它们一个接一个地放入具有固定数量过滤器的代码中一样?
使用已知数量的过滤器:
list.stream().filter(...).filter(...)
编辑:
Sweeper 在他的回答中很好地总结了我的问题,所以再次澄清(可能是未来的读者):我想保留所有满足所有过滤器的对象。
解决方案
我想你想保留所有TestObjects
满足地图指定的所有条件的东西?
这将完成这项工作:
List<TestObject> newList = list.stream()
.filter(x ->
filterMap.entrySet().stream()
.allMatch(y ->
x.getProperty(y.getKey()) == y.getValue()
)
)
.collect(Collectors.toList());
翻译成“英文”,
filter
list
通过保留以下所有元素的列表x
:
- 的所有键值对
y
必须filterMap
满足:
x.getProperty(y.getKey()) == y.getValue()
(我认为我在使这个人类可读方面做得不好......)如果你想要一个更具可读性的解决方案,我推荐 Jeroen Steenbeeke 的回答。
推荐阅读
- firefox - 从书签 (Firefox) 在新选项卡中打开 html 内容
- javascript - 箭头函数分配给没有变量声明关键字的变量?
- node.js - “size”参数在 Nodejs 中必须是 number 类型
- javascript - 反应元素未定义
- ios - Swift如何等到值更改
- python - Django 无法将 ForeignKey 插入数据库:这是错误,MultiValueDictKeyError
- android - 没有找到可以自动化 Chrome '53.0.2785' 的 Chromedriver
- elixir - 如何将十进制转换为整数?
- sql-server - 在 SQL 中求和 json 对象
- cocos2d-x - 如何从 CallFunc 获取更新的参数?(cocos2d-x V3.0)