我有以下搜索条件地图:
pl.stream()
.filter(search.getCriteria("allPilots"))
.forEach(p -> {
p.printl(p.getPrintStyle("westernNameAgePhone"));
});
我以下列方式使用此地图:
pl.stream()
.filter(search.getCriteria("allPilots",45, 56))
.forEach(p -> {
p.printl(p.getPrintStyle("westernNameAgePhone"));
});
我想知道,如何将一些参数传递到谓词图中?
即。我希望通过字符串缩写从地图中获取谓词,并将参数插入从地图谓词中取出的参数。
(void)
以下是link来自我的Google地图谓词方法。
答案 0 :(得分:9)
似乎你想要的不是在Map中存储谓词。您想要的是能够在地图中存储能够从Predicate<Person>
参数创建int
的内容。所以你想要的是这样的:
Map<String, IntFunction<Predicate<Person>>> searchMap = new HashMap<>();
你会这样填写:
searchMap.put("allPilots", maxAge ->
(p -> p.getAge() >= 23
&& p.getAge() <= maxAge));
你会像这样使用它:
Predicate<Person> allPilotsAgedLessThan45 =
searchMap.get("allPilots").apply(45);
当然,如果您创建自己的功能界面会更清楚:
@FunctionalInterface
public MaxAgePersonPredicateFactory {
Predicate<Person> limitToMaxAge(int maxAge);
}
您仍然会以相同的方式填充地图,但在使用时您会有更多可读代码:
Predicate<Person> allPilotsAgedLessThan45 =
searchMap.get("allPilots").limitToMaxAge(45);
答案 1 :(得分:3)
据我了解,您要做的是覆盖命名Predicate
中的一些参数,但我认为这会导致混淆。如果我要求确定某人是否有资格成为飞行员的谓词,我不想担心在我打电话时知道要求是什么。
使用Map
动态生成谓词会很棘手 - 我认为最好的方法是使用Map<String, PredicateFactory>
,其中PredicateFactory
是某种复杂的给出一些参数生成谓词的类:
Map<String, PredicateFactory<T>> predicates = new HashMap<>();
public Predicate<T> get(String name, Object... params) {
return predicates.get(name).apply(params);
}
在我看来,生成“动态”谓词的更好方法是使用静态方法:
public class PredicatesQuestion {
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person(20, Gender.MALE),
new Person(45, Gender.FEMALE), new Person(50, Gender.MALE),
new Person(65, Gender.MALE));
people.stream()
.filter(personIsBetweenAges(16, 25))
.forEach(person -> {
System.out.println(person.getAge() + ", " + person.getGender());
});
}
private static Predicate<Person> personIsMale() {
return person -> person.getGender() == Gender.MALE;
}
private static Predicate<Person> personIsBetweenAges(int lower, int upper) {
return personIsAtLeast(lower).and(personIsYoungerThan(upper));
}
private static Predicate<Person> personIsAtLeast(int age) {
return person -> person.getAge() >= age;
}
private static Predicate<Person> personIsYoungerThan(int age) {
return person -> person.getAge() < age;
}
}
然后根据需要创建描述性谓词是微不足道的:
private static Predicate<Person> personIsOfDrivingAge() {
return personIsAtLeast(17);
}
private static Predicate<Person> couldBePilot() {
return personIsBetweenAges(23, 65).and(personIsMale());
}
你试图通过覆盖一些参数来实现的那种东西仍然很明显,有一点组成:
people.stream()
.filter(couldBePilot().and(personIsBetweenAges(45, 56)))
.forEach(person -> {
System.out.println(person.getAge() + ", " + person.getGender());
});