Java 从 lambda 表达式中的方法返回值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24704791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning a value from a method within a lambda expression
提问by Rogue
I'm trying to figure out how to return a method value from a lambda expression:
我试图弄清楚如何从 lambda 表达式返回方法值:
public int findMissingNumber(Collection<Integer> ints) {
Single<Integer> start = new Single<>(1);
ints.stream().mapToInt(Integer::valueOf).parallel().forEach(i -> {
if (i != start.setValue(start.getValue() + 1)) {
//return here
}
});
return -1;
}
However, it seems that using the return
keyword in the lambda expression will explicitly return to the lambda function itself. Is there some type of way to break or force a return for the entire method?
但是,似乎return
在 lambda 表达式中使用关键字将显式返回到 lambda 函数本身。是否有某种类型的方法可以中断或强制返回整个方法?
采纳答案by Jon Skeet
Is there some type of way to break or force a return for the entire method?
是否有某种类型的方法可以中断或强制返回整个方法?
No. At least, not unless you throw an exception.
不。至少,除非你抛出异常。
Basically, that's not what forEach
is meant for. You could write a method which accepted a function which would return null
for "keep going" and non-null for "stop, and make this the result"... but that method isn'tforEach
.
基本上,这不是forEach
目的。您可以编写一个方法,该方法接受一个函数,该函数将返回null
“继续前进”和非空“停止,并使其成为结果”......但该方法不是forEach
。
The fact that you're using a lambda expression is really incidental here. Imagine you were just calling forEach
and passing in some argument - wouldn't it be reallyweird if that call made your findMissingNumber
method return (without an exception), without the findMissingNumber
method itself having the return statement?
您使用 lambda 表达式的事实在这里真的很偶然。想象一下,您只是在调用forEach
并传入一些参数 -如果该调用使您的方法返回(没有异常),而方法本身没有 return 语句,这会不会很奇怪?findMissingNumber
findMissingNumber
回答by Stuart Marks
(Is this an instance of the XY problem?)
(这是XY 问题的一个实例吗?)
The question is about how to return from a lambda inside a forEach
. Jon Skeetprovided some useful information about findFirst
and also cautioned about side effects in a lambda run in parallel -- both excellent points.
问题是如何从forEach
. Jon Skeet提供了一些关于findFirst
lambda 并行运行中的副作用的有用信息,也警告了这些副作用——这两点都很出色。
But regarding the original question, I'm still thinking: what problem are you trying to solve?
但是对于最初的问题,我还在想:你想解决什么问题?
The method name findMissingNumber
in the example is suggestive. The method takes a collection of numbers as a parameter and iterates over it while incrementing a counter. It returns when it finds a mismatch, or it returns -1 if there is no mismatch. Since the counter is incremented once as each value in the ints
collection is processed, it seems like that collection is expected to be in order, unless a number is missing.
findMissingNumber
示例中的方法名称具有启发性。该方法将一组数字作为参数,并在递增计数器的同时对其进行迭代。它在发现不匹配时返回,如果没有不匹配则返回 -1。由于在ints
处理集合中的每个值时计数器都会递增一次,因此该集合似乎是有序的,除非缺少一个数字。
If so, the parameter ought to be a List
instead of a Collection
. (Making a big assumption here.) Under this assumption, one could rewrite the code using lambdas as streams like so:
如果是这样,参数应该是 aList
而不是 a Collection
。(在这里做一个大假设。)在这个假设下,可以使用 lambdas 作为流来重写代码,如下所示:
static OptionalInt findMissingNumber(List<Integer> ints) {
return
IntStream.rangeClosed(1, ints.size())
.filter(i -> i != ints.get(i-1))
.findFirst();
}
Instead of incrementing a counter, we use IntStream.range
to generate the values expected to be in the list. We then rely on random access to the list to get
values from their expected positions in the list. We filter for the mismatches and return the first one, if any. This avoids mutation and so should run correctly in parallel. (Note that this doesn't parallelize well if the list isn't random-access, though.)
我们不增加计数器,而是使用IntStream.range
生成预期在列表中的值。然后,我们依靠随机访问列表来获取列表中get
预期位置的值。我们过滤不匹配并返回第一个(如果有)。这避免了突变,因此应该并行正确运行。(请注意,如果列表不是随机访问,则这不能很好地并行化。)
The return value is an OptionalInt
which is emptyif no mismatch was found. This is more explicit than using a sentinel value like -1
to indicate the "not found" condition.
如果未发现不匹配OptionalInt
,则返回值为空。这比使用标记值更明确,例如-1
指示“未找到”条件。