将lambdas转换为方法引用

时间:2016-10-12 12:57:51

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

有人可以帮我转换下面的代码来使用方法引用吗?我试图绕过这个新语法,但是当它变得比单个变量映射到单个方法调用更复杂时,我很快就会迷失:

getWorkspaces().stream().forEach((ws) -> {
            DataStoreInfo defaultDataStore = getDefaultDataStore(ws);
            if (defaultDataStore != null) {
                other.setDefaultDataStore(ws, defaultDataStore);
            }
        });

我从这开始,但它不起作用:)

getWorkspaces().stream()
               .map(this::getDefaultDataStore)
               .filter(Objects::nonNull)
               .map(other::setDefaultDataStore);

编辑:通过"它没有工作",我的意思是IDE在" setDefaultDataStore"下的最后一行抱怨它无法解决方法。我希望我能从一些有用的东西开始,但我不知道如何到达那里。我对如何使用方法引用调用一个带有2个参数的方法以及如何映射的方法感到非常困惑。我已经转换了一些看起来像这样的代码:

 getMaps().stream().forEach((m) -> {
            other.add(m);
        });

到此:

getMaps().forEach(other::add);

但是当它变得更复杂时我会迷失方向。我希望有一个明显的解决方案,如何使用方法引用编写相同的代码。

2 个答案:

答案 0 :(得分:3)

您可以在此处阅读有关方法参考的大量有用信息 https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

如果你的lambda除了调用现有方法之外什么都不做,你可以用方法引用替换它。因此,如果您对lambdas感到满意,您将轻松应对方法参考。

它们有4种

  1. 引用静态方法 - ContainingClass :: staticMethodName
  2. 引用特定的实例方法 object - containingObject :: instanceMethodName
  3. 对实例的引用 特定任意对象的方法 type - ContainingType :: methodName
  4. 参考a 构造函数 - ClassName :: new
  5. 回到你的问题: .MAP(其他:: setDefaultDataStore);

    您不应该使用map函数对流成员执行某些辅助操作,它用于将流转换为另一个。用户foreach而不是

    getWorkspaces().stream()
                   .map(this::getDefaultDataStore)
                   .filter(Objects::nonNull)
                   .foreach(other::setDefaultDataStore);
    

答案 1 :(得分:2)

你可以将你的代码转换为这样的lambda版本,但它并不像预期的那样干净。

words.stream().map(ws -> new SimpleImmutableEntry<>(ws, getDefaultDataStore(ws)))
              .filter(e -> e.getValue() != null)
              .forEach(e -> setDefaultDataStore(e.getKey(), e.getValue()));

注意:e是入场的缩写。