在处理转换时(例如:转换List<People> people
到List<Integer> ages
,其中People
是一个包含属性age
的类),通常有两种方式(对于我这样做:
使用java8:
people.stream().map(p -> p.getAge()).collect(toList())
;
或用户guava2:
Lists2.transform(people, People2AgeTransformer.INSTANCE);
其中People2AgeTransformer
是一个变换器,它实现了Function接口以返回年龄。
最近,我偶然发现java8和guava可以合并,因此代码可以是:
Lists2.transform(people, p->p.getAge());
这段代码符合并运行没有任何错误,这让我感到困惑。
方法Lists2.transform()
要求第二个args是接口com.google.common.base.Function
的实现,而java8 lambda实际上是接口java.util.function.Function
的实现。(好吧,它们都声明了一个方法{{1将A转换为B。)
我不明白为什么这会起作用,因为它们是不同包的两个不同界面。
答案 0 :(得分:8)
java8 lambda实际上是接口
的实现java.util.function.Function
不,不是。 p -> p.getAge()
没有预定义类型 - 在编译时它的类型是推断,具体取决于它所调用的上下文。任何具有int/Integer getAge(Person p)
方法的功能界面都可以使用。
因此,java.util.Function<Person, Integer>
和com.google.common.base.Function<Person, Integer>
都是兼容的。
答案 1 :(得分:1)
如果您将一个函数分配给变量或通过参数传递,那么通过Java-8方法引用很容易使它们适应:
java.util.function.Function<Person, Integer> javaFunction = p -> p.getAge();
com.google.common.base.Function<Person, Integer> guavaFunction = javaFunction::apply;
java.util.function.Function<Person, Integer> javaFunction2 = guavaFunction::apply;
因此,如果您已在变量Function
中拥有Java 8 fn
对象并需要将其传递给某些Guava代码,请使用fn::apply
。如果变量Predicate
中有Java 8 pred
,请在将其传递给Guava代码时使用pred::test
。类似的方法引用可以用于其他功能接口。