Java 8和流上的聚合操作

3
当我们使用像 filter, mapToInt, sum 等方法,并将它们传递给 lambda 表达式时,我不明白操作本身是方法还是我们传递的 lambda 表达式。
我想知道正确的术语。
我认为 lambda 是函数,因此是我们传递给使用它来生成结果的方法的操作。
为什么也说 filter, sum等是使用函数作为参数的操作?
两种说法都正确吗?
4个回答

5

流方法和它们接受的lambda参数,总的来说,都是操作。一旦我们习惯了将函数作为方法调用的参数,这就不会让人感到困惑。Stream方法将它所接收到的函数应用于流中的值,以产生一个新的流(中间方法)或产生一些聚合结果(终端方法)。

更详细的解释,请参见http://www.lambdafaq.org/why-are-lambda-expressions-being-added-to-java/


1
Lambda是一个函数/回调,通常作为参数传递。为了理解这一点,考虑您需要在列表中搜索一个值:
Java 7:
int i = Arrays.asList(1,2,3,4,5,6).indexOf(3);

这将返回一个单一元素。现在,如果需要更动态的请求,可以使用for循环收集这些项目。但是,如果希望以类似的方式执行此操作,则可以将lambda作为参数传递:
Java 8(可能的写法):
List<Integer> collect = asList(1, 2, 3, 4, 5, 6).filter(x -> x >= 2 && x < 4);

真正的Java 8 API示例略显冗长:

List<Integer> collect = Arrays.asList(1, 2, 3, 4, 5, 6)
    .stream()
    .filter(x -> x >= 2 && x < 4)          
    .collect(Collectors.toList());

1
我不确定这是否被广泛接受,但我认为如下所述:
函数是一种接收参数并产生值的东西,理想情况下没有副作用(尽管在Java中无法强制执行)。如果你想强调数学/函数方面,可以使用它。
子程序/过程是一段被命名的代码,用于其副作用而重复使用。
方法是在Java中实现/编写函数和子程序的方式。没有不属于某个类的函数或过程。
在Java中,lambda表达式是一种编写方法(某个匿名类实现功能接口)并同时获得对该接口实例的引用的方法。
操作是函数或过程。
因此,取决于您想从哪个角度看待它:由于它涉及Java,您可以将所有内容都称为“方法”。但有时您想强调不同的方面。就像您的示例中:
筛选、求和等是使用函数作为其参数的操作
在这里,我们可以说:“'filter'是一个以函数接口引用为参数的方法”,但这会改变句子的意图。

Lambda表达式不是语法糖:请参见http://programmers.stackexchange.com/a/181743/59134 - Maurice Naftalin
@MauriceNaftalin 我理解技术要点。但是你看,OP对术语已经感到足够困惑了,所以暂时把lambda表达式当作那样想并不会有害 - 只是为了让它们变得更加清晰易懂。尽管如此,我仍然会编辑我的帖子,以免引入另一个令人困惑的术语,比如“语法糖”。 - Ingo

0

记住,我们传递给过滤器的函数只是一个过滤逻辑。而过滤函数已经期望一个具有过滤逻辑的函数。过滤函数专门接受返回布尔值的函数,并决定是否传递流中当前元素或者简单地丢弃它。

我希望我正确理解了你的问题。关于流的更多信息,请参阅Java 8 Stream API系列文章amitph.com > Java 8 Streams API Tutorials


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接