java 8函数调用

时间:2015-06-18 16:22:25

标签: java lambda functional-interface

我过去几个月一直在使用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; }

2 个答案:

答案 0 :(得分: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));
}

答案 1 :(得分:6)

如果你是一个很长时间的Java编码器,新的lambda东西可能会令人困惑 - 对我来说它是(对吗?)。 Lambdas是一个上下文构造,编译器根据其使用的上下文进行解释,就像许多其他脚本语言一样。对于大多数情况,您永远不需要创建自己的子类型,因为编译器会根据您使用它们的位置为您执行此操作。客观地说,我们认为,“是的,我知道。杜。”但是让你的大脑改变思维模式很难。这是我认为许多开发人员需要克服的重大障碍之一。

我可以看到我们想要怎么想,“哎呀,我想要自己的BiConsumer连接两个Strings并将它们添加到List。”所以你在你喜欢的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)Runnable.run()。在这些情况下,您只需将lambda结构内联。

因此,在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不能很好地搭配。