从lambda表达式中的方法返回值

我试图弄清楚如何从lambda表达式返回一个方法值:

public int findMissingNumber(Collection ints) { Single start = new Single(1); ints.stream().mapToInt(Integer::valueOf).parallel().forEach(i -> { if (i != start.setValue(start.getValue() + 1)) { //return here } }); return -1; } 

但是,似乎在lambda表达式中使用return关键字将显式返回lambda函数本身。 是否有某种类型的方法可以打破或强制返回整个方法?

是否有某种类型的方法可以打破或强制返回整个方法?

不,至少,除非你抛出exception。

基本上,这不是forEach的意思。 你可以编写一个接受一个函数的方法,该函数将为“keep going”返回null ,而对于“stop,则返回非null”,但是这个方法不是 forEach

你使用lambda表达式的事实在这里是偶然的。 想象一下,你只是调用forEach并传入一些参数 – 如果调用使你的findMissingNumber方法返回(没有exception),而findMissingNumber方法本身没有return语句,那不是奇怪吗?

(这是XY问题的一个实例吗?)

问题是如何从forEach的lambda返回。 Jon Skeet提供了一些关于findFirst有用信息,同时也警告了lambda并行运行中的副作用 – 这两点都很优秀。

但对于最初的问题,我仍然在想:你想解决什么问题?

示例中的方法名称findMissingNumber是暗示性的。 该方法将一组数字作为参数,并在递增计数器时对其进行迭代。 它在找到不匹配时返回,或者如果没有不匹配则返回-1。 由于计数器在处理整个集合中的每个值时递增一次,因此除非缺少数字,否则看起来该集合应该是有序的。

如果是这样,参数应该是List而不是Collection 。 (在这里做一个很大的假设。)在这个假设下,人们可以使用lambdas重写代码,如下所示:

 static OptionalInt findMissingNumber(List ints) { return IntStream.rangeClosed(1, ints.size()) .filter(i -> i != ints.get(i-1)) .findFirst(); } 

我们使用IntStream.range来生成预期在列表中的值,而不是递增计数器。 然后,我们依赖于对列表的随机访问,以从列表中的预期位置get值。 我们过滤不匹配并返回第一个,如果有的话。 这可以避免突变,因此应该并行正确运行。 (请注意,如果列表不是随机访问,则不会很好地并行化。)

返回值是OptionalInt ,如果未找到不匹配,则为 。 这比使用像-1这样的标记值来表示“未找到”条件更明确。