将lambda作为参数传递给泛型类型 - java 8

时间:2016-01-11 17:21:35

标签: java generics lambda java-8

如果我有方法foo(Predicate bar),我可以使用下一步:

foo(new Predicate<MyObject>() {
        public boolean apply(MyObject obj) { 
           return true;
        }
    }
)

但是如何使用lambda样式表达式获得相同的结果:

foo((MyObject obj) -> true); //obvious compile exception

如何将带有lambda的泛型类型传递给方法? 或者,简单地说,如何使用没有局部变量的lambda样式创建类Predicate(或其他)的匿名对象。

2 个答案:

答案 0 :(得分:3)

不要使用原始类型foo(Predicate<? extends MyObject> bar)

或者在lambda foo(obj -> ((MyObject) obj).myMethod())

内投射

答案 1 :(得分:1)

如果你的目标类型是一个原始类型,就像调用foo(Predicate bar)一样,你不能指望lambda表达式为你神奇地生成一个合适的类型。它适用于匿名内部类,因为该声明具有显式类型(Predicate<MyObject> {}),可以在不安全的操作中传递给Predicate。但是lambda表达式没有类型。它们将转换为目标类型,在调用中,目标类型为Predicate

如果要通过lambda表达式创建Predicate<MyObject>,则需要Predicate<MyObject>作为目标类型:

Predicate<MyObject> p = o -> /* note that o has the type MyObject */true;
foo(p);

foo((Predicate<MyObject>)o -> /* here, o has the type MyObject as well*/true);

void fooHelper(Predicate<MyObject> p) {
    foo(p);
}
…
fooHelper(o -> /* here, o has again the type MyObject*/true);

当然,在所有这些情况下,您也可以编写(MyObject o) -> true,但参数的这个显式声明对类型没有影响使用此lambda表达式创建的实例。

请注意,第二个变体具有类型转换的正式结构,但在运行时不会有类型转换操作。它仅用于指定lambda表达式的目标类型(类似于用于在方法调用中选择特定重载的加宽转换)。