【问题标题】:Composing Java 8 method references in stream collector在流收集器中编写 Java 8 方法引用
【发布时间】:2016-10-03 22:34:58
【问题描述】:

我想在流的 collect(Collectors.toMap(..)) 调用中编写方法引用。在下面的示例中,我的代码可以在没有方法引用的情况下完成我的任务:

class A {
    private String property1;
    private B property2;

    public String getProperty1() { return property1; }
    public B getProperty2() { return property2; }
}

class B {
    private String property3;

    public String getProperty3() { return property3; }
}

public class Main {
    public static void Main() {
        List<A> listOfA = /* get list */;

        Map<String, String> = listOfA.stream()
            .collect(toMap(x -> x.getProperty1(), x -> x.getProperty2().getProperty3()));
    } 
}

x -&gt; x.getProperty1() 更改为A::getProperty1() 很简单。然而,x -&gt; x.getProperty2().getProperty3() 并不是那么简单。我希望以下其中一项工作:

.collect(toMap(A::getProperty1, ((Function)A::getProperty2).andThen((Function)B::getProperty3)))

.collect(toMap(A::getProperty1, ((Function)B::getProperty3).compose((Function)A::getProperty2)))

但是,他们都给了我错误Non-static method cannot be referenced from static context

【问题讨论】:

  • 没有比这更好的方法了。原始 lambda 是您将获得的最佳值。
  • 您最终得到的每个答案都将比 lambda 表达式更长、更笨拙且更难以阅读。为什么要使用其他方式?
  • 我主要是出于好奇而探索这一点,至少在这个问题的特殊表述中是这样。即使是我提供的两个示例(不起作用)也比 lambda 更笨重且可读性差。但是,方法组合是一个强大的功能,如果可以的话,我会更频繁地使用它。如果你们中的任何一个可以解释为什么不允许这样做,另外在哪些情况下我可以使用方法组合(例如,如果所有方法都是静态的,这可能吗?),那将非常有用并且值得接受在我看来回答。不管怎样,谢谢!
  • 我不希望有 任何 种无需演员阵容就可以实现的情况。问题是 A::getProperty2 可能是 any 函数接口,带有一个恰好返回 java.util.function.FunctionandThen 方法,而 Java 无法为您推断。
  • 方法引用是一组非常有限的 lambdas 的简写。每个人,在第一次遇到它们时,都想找到方法来扩展它们以涵盖更多情况(链接、绑定参数等)——但是一旦你超越了仅仅命名一个方法,好处就不存在了,所以这就是速记停止。

标签: java java-8 java-stream method-reference collectors


【解决方案1】:

A::getProperty2 是一个Function&lt;A, B&gt;(这是一个接受 A 实例并返回 B 实例的函数)。

您可以将其转换为:

((Function<A, B>)A::getProperty2).andThen(B::getProperty3)

或者您可以创建一个函数生产者,例如:

public static <A, B, R> Function<A, R> compose(
        Function<A, B> f1, Function<B, R> f2) {
    return f1.andThen(f2);
}

并用它来组成:

compose(A::getProperty2, B::getProperty3)

【讨论】:

  • A::getProperty2Function 的有效方法引用,它根本不能用作Supplier,因为它需要A 类型的参数。
  • 所以我的错误是将其转换为Function 而不是Function&lt;A,B&gt;,正如您所澄清的那样。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多