5

过去几个月我一直在使用 Java 8,并试图了解 lambdas。我对演唱会有点了解。但是在将自定义功能接口执行为 lambda 调用时苦苦挣扎。

如果我创建 java Bifuctional 接口实现

BiFunction<t1,t2,R> trade = (t1, t2) -> {
  // calling another method for merger
  return t1,t2;
};

我可以像下面那样将其称为 lambda 吗?

(a, b)-> trade: 

还是我必须创建执行方法?

private int execute(BiFunction<t1,t2,R> trade, int a, int b){ 
    return trade.apply(a, b)
}

下面是调用 lambda 的代码示例:

BiFunction<t1,t2,R> trade = (t1, t2) -> {
                                         // calling another method for merger return t1+t2;
                                        };

public static void main(String[] args) {
  execute(trade , 1, 2);
}

private int execute(BiFunction<t1,t2,R> trade, int a, int b) {
  return trade.apply(a, b);
}

我很好奇为什么编译器不能理解这个

public static void main(String[] args) { int i= (1,2) -> trade; }
4

2 回答 2

7

你像这样使用 lambda

public static void main(String[] args) {
    BiFunction<Integer, Integer, Integer> add = (x, y) -> {
        return x + y;
    };
    System.out.println(add.apply(1, 2));
}
于 2015-06-18T16:41:05.613 回答
6

如果您是一名长期的 Java 编码员,那么新的 lambda 内容可能会令人困惑——对我来说是(是?)。Lambda 是一种上下文构造,编译器根据使用它的上下文进行解释,就像许多其他脚本语言一样。在大多数情况下,您永远不需要创建自己的子类型,因为编译器会根据您使用它们的位置为您完成它。客观地,我们认为,“是的,我知道。Duh。” 但是让你的大脑改变思维模式是很困难的。这是我认为很多开发人员需要克服的一大障碍。

我可以看到我们想怎么想,“哎呀,我想要我自己的BiConsumer,它连接两个Strings并将它们添加到 aList中。” 所以你在你最喜欢的 IDE 中生成你的类文件并得到

public static class StringConcat implements BiConsumer<String,String>{
    private List<String> values = new ArrayList<>();

    @Override
    public void accept(String s, String s2) {
        values.add(s,s2);
    }
}

当你去尝试为它找到一个好的用途时,你似乎真的找不到一个。那是因为没有必要创建一个。

我一直很难找到需要创建自己的类来实现任何java.util.function东西的情况。不是说没有病例,我只是没有找到太多。

它归结为识别您何时拥有采用具有单一抽象方法的类型的东西,例如Comparable.compare(T t1, T t2)or Runnable.run()。在这些情况下,您只需内联 lambda 构造。

所以使用 my 的功能StringConcat,给定一个Map<String,String> map

    // I just passed it a new BiConsumer!
    map.forEach((k,v)-> list.add(k+v));


编辑:在您发表评论并重新阅读您的问题之后,我认为您仍然有一些心理障碍。看起来您想要声明一个 lambda,实例化它并分三个不同的步骤调用它。这样就违背了目的。当您使用 lambdas 时,您在创建 lambda 内联函数时执行前两个步骤。

//                      declare AND instantiate
stringList.stream().map(string -> Integer.parseInt(string))...

这就是说,“对于列表中的每个字符串,应用这个函数,Integer.parseInt(string)。” 请注意,您永远不会调用apply(). 这是在map方法内完成的。这避免了需要做你正在做的事情来创建一个实例并单独尝试调用它。

Lambda 不是灵丹妙药。在大多数情况下,您仍然需要使用具有不同语句的单独方法。也许你想要的功能不能很好地与 lambdas 配合使用。

于 2015-06-18T17:36:21.133 回答