java 8个函数调用

java 8 function invocation

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

如果我创建 java 双功能接口实现

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; }

你这样使用 lambda

public static void main(String[] args) {
    BiFunction<Integer, Integer, Integer> add = (x, y) -> {
        return x + y;
    };
    System.out.println(add.apply(1, 2));
}

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

我明白我们是怎么想的,"Gee, I want my own BiConsumer that concatenates two Strings and adds them to a List." 所以你在你最喜欢的 IDE 中生成你的 class 文件并得到

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);
    }
}

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

我很难找到需要创建自己的 class 来实现任何 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、实例化它并通过三个不同的步骤调用它。这种做法违背了目的。当您使用 lambda 时,当您创建 lambda 内联时,您会执行前两个步骤。

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

这就是说,"for every string in the list, apply this function, Integer.parseInt(string)." 注意你永远不会调用 apply()。这是在 map 方法中完成的。这避免了需要做你正在做的创建一个实例并单独尝试调用它。

Lambda 不是灵丹妙药。在大多数情况下,您仍然需要具有不同语句的单独方法。也许您想要的功能与 lambda 表达式不兼容。