假设我有一个外部JSON:
[{
"condition": "equals",
"field": "name",
"value": "jack"
},
{
"condition": "greater",
"field": "age",
"value": 25
}
]
这意味着我想在名为"jack"
和age > 25
的人员的Person对象列表中查看。使用Java 8过滤相当简单(显示的示例仅在名称上过滤)。
但是,我想让这个过滤器可配置,并且还应用多个过滤器。假设下面的Person pojo(这是不言自明的),取名字和年龄,我怎样才能使过滤器动态或可配置?
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Accessors and Mutators
}
List<Person> persons = Arrays.asList(
new Person("mkyong", 30),
new Person("jack", 20),
new Person("lawrence", 40)
);
Person result1 = persons.stream() // Convert to steam
.filter(x -> "jack".equals(x.getName())) // we want "jack" only
.findAny() // If 'findAny' then return found
.orElse(null);
我期待一个符合条件的Person对象列表作为结果。
答案 0 :(得分:6)
就我所知,这与streams
本身没什么关系。该过滤方法只是一个Predicate
,可以作为实例提供,例如从您可以创建的工厂方法中提供。
static Predicate<Person> fromName(String value){
return p -> p.getName().equals(value);
}
假设您有另一种方法:
static Predicate<Person> fromAge(int value) {
return p -> p.getAge() == value;
}
由于存在Predicate.and
,Predicate.or
,您可以这样做:
fromAge(12).and(fromName("jack"));
因此链接你的谓词
答案 1 :(得分:2)
这有两种方法。
您可以直接串联调用所需的过滤器:
Person result1 = persons.stream()
.filter(x -> "jack".equals(x.getName()))
.filter(x -> 25 > x.getAge()) // new filter
.findAny()
.orElse(null);
或者,您有自己的类实现Predicate<Person>
。
在这种情况下,您可以使用构建器模式逐步构建谓词。
您必须面对的困难如下:
&&
vs ||
)(a && b) || c
不是a && (b || c)
)请注意,Predicate
有方便的and
和or
方法来链接谓词。