【问题标题】:can i combine java8 (stream, lambda) and guava?我可以结合java8(流,lambda)和番石榴吗?
【发布时间】:2025-12-30 21:45:07
【问题描述】:

在处理转换时(例如:将List<People> people 转换为List<Integer> ages,其中People 是一个包含属性age 的类),通常有两种方法(对我来说)这样做:

  1. 使用java8:

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

  2. 或用户 guava2:

    Lists2.transform(people, People2AgeTransformer.INSTANCE); 其中People2AgeTransformer 是一个转换器,它实现了 Function 接口以返回年龄。

最近无意中发现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。 )

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

【问题讨论】:

    标签: java lambda guava java-stream


    【解决方案1】:

    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> 都是兼容的。

    【讨论】:

      【解决方案2】:

      如果你有一个分配给变量或通过参数传递的函数,那么通过 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。类似的方法引用可以用于其他功能接口。

      【讨论】: