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

2022-09-01 18:59:47

我正在尝试弄清楚如何从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;
}

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


答案 1

有没有某种类型的方法来破坏或强制整个方法的返回?

不。至少,除非您抛出异常,否则不会。

基本上,这不是本意。你可以写一个方法,它接受一个函数,该函数将返回“keep continue”,非null返回“stop,并使此成为结果”......但该方法不是.forEachnullforEach

您使用 lambda 表达式的事实是偶然的。想象一下,你只是调用并传递一些参数 - 如果该调用使你的方法返回(无一例外),而方法本身没有返回语句,那不是很奇怪吗?forEachfindMissingNumberfindMissingNumber


答案 2

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

问题是关于如何从 .Jon Skeet提供了一些有用的信息,并警告了并行lambda运行的副作用 - 这两个优点都是很好的。forEachfindFirst

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

示例中的方法名称具有启发性。该方法将数字集合作为参数,并在递增计数器时循环访问该集合。当它发现不匹配时返回,或者如果没有不匹配,它返回 -1。由于在处理集合中的每个值时计数器递增一次,因此除非缺少数字,否则该集合似乎应按顺序排列。findMissingNumberints

如果是这样,则该参数应为 a 而不是 .(在这里做一个很大的假设。在这种假设下,可以使用lambdas作为流来重写代码,如下所示:ListCollection

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

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

如果未发现不匹配项,则返回值为。这比使用哨兵值(如指示“未找到”条件)更明确。OptionalInt-1


推荐