谓词#和Groovy 2.2闭包
我的Java 8代码运行良好:谓词#和Groovy 2.2闭包,groovy,java-8,predicate,Groovy,Java 8,Predicate,我的Java 8代码运行良好: //Java 8 @Test public void testPredicates(){ Predicate<Integer> p1 = (i) -> true; Predicate<Integer> p2 = (i) -> true; Predicate<Integer> p3 = p1.and(p2); List<Integer> is = new ArrayLi
//Java 8
@Test public void testPredicates(){
Predicate<Integer> p1 = (i) -> true;
Predicate<Integer> p2 = (i) -> true;
Predicate<Integer> p3 = p1.and(p2);
List<Integer> is = new ArrayList<>();
is.add(1);
is.add(2);
assertTrue(is.stream().allMatch(p1.and(p2)));
}
如果我将断言替换为justassert(is.stream().allMatch(p1))
,那么测试将成功完成。问题是调用谓词上的和
方法
例如,在调试器中检查p2
,我可以看到它的类型为OneParameterTest$\u test\u closure2
。反编译字节码验证了这一点
我有一种感觉,尽管我不确定,这与隐式闭包协同作用有关(参见)
有没有办法编写Groovy代码,以便它将谓词创建为java.util.function.predicate
的真实实例
有没有办法编写Groovy代码以便创建谓词
作为java.util.function.Predicate的真实实例
您在那里所做的是创建谓词的真实实例。问题是您创建它们的方式实际上只对单个方法接口有用。谓词定义了几个方法。有几种方法可以做到这一点。也许最简单的方法是利用Groovy的映射到接口支持。下面的代码只解释了“and”和“test”,但您可以提供实际调用的任何内容,而忽略其他内容
很难从您的代码片段中说出您真正想要完成的是什么,但仅为了解决您编写的特定测试,您应该能够执行类似的操作。测试方法都是硬编码的,在这里返回true,就像在您的测试中一样,但是您可能在那里有真正的逻辑
Predicate<Integer> p1 = [test:{ t -> true},
and: { Predicate other -> [test: { t -> true}] as Predicate}] as Predicate
// in your example you are never calling p2.and(...), but
// it is included here for consistency with the one above...
Predicate<Integer> p2 = [test:{ t -> true},
and: { Predicate other -> [test: { t -> true}] as Predicate}] as Predicate
// it isn't clear why you are creating p3, but you can...
Predicate<Integer> p3 = p1.and(p2)
List<Integer> is = new ArrayList<>()
is.add(1)
is.add(2)
assert(is.stream().allMatch(p1.and(p2)))
谓词p1=[test:{t->true},
和:{Predicate other->[test:{t->true}]作为谓词}]作为谓词
//在您的示例中,您从未调用p2.和(…),而是
//为了与上面的一致性,这里包含了它。。。
谓词p2=[测试:{t->true},
和:{Predicate other->[test:{t->true}]作为谓词}]作为谓词
//不清楚你为什么要创建p3,但你可以。。。
谓词p3=p1和(p2)
List is=new ArrayList()
is.add(1)
is.add(2)
断言(is.stream().allMatch(p1.and(p2)))
实际上,问题在于Groovy 2.3的早期版本忽略了接口中定义的默认方法
来自Groovy 2.3:
Groovy 2.3不支持Java8提供的新语法结构
(如lambdas、方法引用、接口中的默认方法、,
等等),但您已经可以很好地使用JDK 8提供的新API了,
甚至使用Groovy闭包代替Java8Lambdas
在2.3.8和2.4中,它是固定的(至少在上述情况下是固定的),作为的一部分,如果您编写
allMatch(p3)
,groovy版本可以工作吗?关于您的问题,有两个小评论:1)您从来没有使用过p3
,2)在Java8中您有p1.和(p2)
,在groovy中您有p2.和(p1)
p3,注意相反的顺序。好的观点,但没有问题。在谓词上调用“and”是个问题。我尝试了Groovy 2.3(支持Java 8),得到了相同的结果。也许可以将其发布到groovy用户邮件列表中?好的,我已经发布了-让我们看看是否有任何回复…我意识到这个示例实际上没有做任何有用的事情,但它做了原始帖子中的测试尝试做的事情。也许你可以从这里找到答案,或者如果你能更好地描述真正的问题,我可以给你一个解决方案。不管怎样,我希望这有帮助。
java.lang.ClassCastException: java.lang.Boolean
cannot be cast to java.util.function.Predicate
Predicate<Integer> p1 = [test:{ t -> true},
and: { Predicate other -> [test: { t -> true}] as Predicate}] as Predicate
// in your example you are never calling p2.and(...), but
// it is included here for consistency with the one above...
Predicate<Integer> p2 = [test:{ t -> true},
and: { Predicate other -> [test: { t -> true}] as Predicate}] as Predicate
// it isn't clear why you are creating p3, but you can...
Predicate<Integer> p3 = p1.and(p2)
List<Integer> is = new ArrayList<>()
is.add(1)
is.add(2)
assert(is.stream().allMatch(p1.and(p2)))