列出forEach方法参考说明

时间:2017-12-23 05:39:28

标签: java lambda

过去几个月我一直在学习java,刚开始学习lambda函数。我最近切换了我的IDE并在这样的代码上注意到“可以用方法引用替换”的警告。

   List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        intList.add(3);

        intList.forEach(num -> doSomething(num));

    voiddoSomething(int num) {
        System.out.println("Number is: " + num);
    }

经过一番挖掘,我意识到这不是行

 intList.forEach(num -> doSomething(num));

我可以使用

 intList.forEach(this::doSomething);

这真是太棒了。几天前我甚至不知道lambdas并且正在使用for循环来做这样的操作。现在我用lambdas替换了我的for循环,甚至更好,我可以用方法引用替换我的lambdas。问题是我并不真正理解这一切是如何在内部发挥作用的。任何人都可以解释或提供一个很好的资源,解释如何调用doSomething函数,并在我们使用方法引用时将参数传递给它吗?

3 个答案:

答案 0 :(得分:1)

双冒号运算符只是一个便利运算符,用于执行lambda正在执行的操作。有关详细信息,请查看此页面:https://javapapers.com/core-java/java-method-reference/

答案 1 :(得分:1)

双冒号只是用于定义lambda表达式的语法糖,其参数和返回类型与现有函数相同。它的创建是为了让Lambda能够更容易地与现有的代码库一起添加。

调用forEach对象的List<Integer>方法将任何实现Consumer功能接口的对象作为参数。你的lambda num -> doSomething(num)本身恰好符合这个界面的形式要求。

因此,您可以使用双冒号作为该lambda表达式的语法糖。

通常,如果您的对象obj使用方法func,它接受​​参数params...,那么写obj::func等同于lambda (params...) -> obj.func(params...)

在你的情况下,othis(当前对象),它有一个方法doSomething(),它接受​​一个整数参数,因此,this::doSomething相当于num -> doSomething(num)

答案 2 :(得分:1)

鉴于你已经提到过,直到最近你才开始进入函数式编程,我希望尽可能保持简单和直接,但请注意,只要你提供的代码很少,我们就可以得到<从事物的高级视图以及低级视图中都可以看到很多。

  

任何人都可以解释或提供一个很好的资源来解释如何   调用doSomething函数并将参数传递给它   当我们使用方法参考?

无论我们使用internal iteration还是lambda表达式,

如何调用doSomething函数都留给库(method reference),所以基本上我们指定是什么不是我们为forEach方法提供的一个行为(一个函数)我们想要为源intList的每个元素执行的行为(一个函数)的意义,而不一定是它应该如何进行它的工作

然后将其留给库,以便为源doSomething的每个元素应用(执行)intList的指定函数。

Method references可以看作是lambda只调用特定方法的简写。这里的好处是通过明确地引用特定的方法名称,您的代码获得了更好的可读性,因此,使其更易于阅读和遵循,并且在大多数情况下,使用方法引用读取代码作为问题陈述读取是一件好事。 / p>

同样重要的是要知道不能将任何给定的函数传递给forEach terminal operation,因为每个接受行为的方法都对允许的函数类型有限制。这是通过在functional interfaces包中使用java.util.function来完成的。

最后但并非最不重要的是,在重构方面,并不总是可以使用方法引用,也不总是使用lambdas expressions代替我们在Java-8之前使用的代码。但是,当您继续学习Java-8功能时,可以尝试一些改进代码的技巧: