我可以结合使用 java8 (stream, lambda) 和 guava 吗?

can i combine java8 (stream, lambda) and guava?

处理转换时(例如:将 List<People> people 转换为 List<Integer> ages,其中 People 是包含 属性 [=15= 的 class ]), 通常有两种方法(对我来说):

  1. 使用java8:

    people.stream().map(p -> p.getAge()).collect(toList());

  2. 或用户 guava2:

    Lists2.transform(people, People2AgeTransformer.INSTANCE); 其中 People2AgeTransformer 是一个转换器,它实现了 return 年龄的函数接口。

最近偶然发现java8和guava可以结合,所以代码可以是:

Lists2.transform(people, p->p.getAge());

这段代码符合并运行正常,没有任何错误,这让我很困惑。 方法 Lists2.transform() 要求第二个参数是接口 com.google.common.base.Function 的实现,而 java8 lambda 实际上是接口 java.util.function.Function 的实现。(好吧,他们都声明了一个方法 B apply(A input) 将 A 转换为 B。)

我不明白为什么这会起作用,因为它们是不同包的两个不同接口。

the java8 lambda is actually the implementation of interface java.util.function.Function

不,不是。 p -> p.getAge() 没有预定义类型 - 它的类型在编译时是 inferred,具体取决于调用它的上下文。任何具有 int/Integer getAge(Person p) 方法的功能接口都可以工作。

因此 java.util.Function<Person, Integer>com.google.common.base.Function<Person, Integer> 都兼容。

如果您有一个函数分配给变量或通过参数传递,通过 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;

因此,如果您已经在变量 fn 中有 Java 8 Function 个对象并且需要将其传递到一些 Guava 代码中,只需使用 fn::apply。如果变量 pred 中有 Java 8 Predicate,则在将其传递给 Guava 代码时使用 pred::test。类似的方法参考可以用于其他功能接口。