谓词#和Groovy 2.2闭包

谓词#和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代码运行良好:

//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)));
}
如果我将断言替换为just
assert(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)))