我目前正在实现一种将谓词与文本字符串匹配的方法
要进行匹配,我先填充
问题在于,当像下面的代码中那样使用参数化谓词时,相同的谓词会匹配不同的参数(哈希函数中未使用valueToTest)
public static Predicate<MyObject> predicateCondition(String valueToTest) {
return myObject -> myObject.value.equals(valueToTest);
}
所以目前我需要为每个要测试的参数做一个谓词,即:
public static Predicate<MyObject> predicateConditionValue1() {
return myObject -> myObject.value.equals("value1");
}
public static Predicate<MyObject> predicateConditionValue2() {
return myObject -> myObject.value.equals("value2");
}
还有另一种避免重复谓词的方法吗?
答案 0 :(得分:1)
tl; dr:
首先,您应该知道谓词不是类,而是interface。 而且lambda几乎是anonymous classes(几乎没有区别,在您的问题范围内并不重要)。 因此,您在问题中显示的所有三个函数都返回作为三个不同类的实例的对象(当然,它们全部实现相同的接口,这就是为什么您可以在Map中将它们全部用作键)的原因。 但是map(实际上也是接口,因此您需要了解在代码中使用的确切地图实现的工作方式)通常使用键类的equals(),hashCode()甚至有时使用compareTo()。并且因为您使用的是匿名类(严格来说:“几乎匿名的类”),所以它使用类Object中的equals()和hashCode()。 hashCode()不依赖于对象方法和数据,而是由JRE创建的,而equals()比较该哈希码。
简短地:
请勿在地图中使用匿名(声明为lambda)谓词作为键。创建自己的实现Predicate接口的类,并拥有自己的hashCode(),equals()和test()实现。如果仍要使用lambda,请使用这些匿名谓词作为您自己的键类的字段。
通常:
为避免此类问题,只需将Java中的Lambda视为语法糖(lambda不仅是语法糖,而且几乎是语法糖)。在编写代码时:
Predicate<String> aPredicate= s->"asd".equals(s);
将其视为下面的特殊代码形式:
Predicate<String> aPredicate= new Predicate<String>() {
@Override
public boolean test(String s) {
return "asd".equals(s);
}
};
答案 1 :(得分:0)
您也可以改用BiFunction
:
BiFunction<MyObject, String, Boolean> isEquslTo = (myObject, expected) -> Objects.equals(myObject.value, expected);
但是我喜欢另外两个Predicate
的方法。
答案 2 :(得分:0)
为避免谓词重复,您应该使用BiPredicate<T,U>
,它接受一个以上的参数并产生一个Boolean
。
BiPredicate<MyObject, String> biPredicate = (obj, string) -> myObject.value.equals(string)
在一种方法中:
public static BiPredicate<MyObject, String> predicateConditionValue() {
return (myObject, string) -> myObject.value.equals(string);
}