Stream.forEach() 中的 `return;` 在哪里中断控制?

lik*_*udo 0 java java-8

哪里return;Stream.forEach()休息控制?

我预计在打印此语句后,forEach 将退出并进入方法的其余部分。

返回 nMissing: 2

但是相反,我发现它反而返回处理流的其余部分。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class MissingKInteger {
    int currentItem = 0;
    int nMissing = 0;
    ArrayList<Integer> al = new ArrayList<Integer>();

    public int findKthPositive(int[] arr, int k) {
        Arrays.stream(arr).forEach(x -> {
            System.out.format("--- examine x %d ---\n", x);
            if (x - currentItem == 1) {
                currentItem++;
                System.out.format("step. currentItem %d, nMissing %d\n", currentItem, nMissing);
            } else {
                do {
                    nMissing++;
                    currentItem++;
                    al.add(currentItem);
                    System.out.format("loop. currentItem %d, nMissing %d\n", currentItem, nMissing);
                    if(nMissing == k) {
                        System.out.format("returning nMissing: %d" , nMissing);
                        return;             
                    }
                } while (x - currentItem > 1);
                currentItem = x;
            }
            System.out.format("out of loop. currentItem %d, nMissing %d\n", currentItem, nMissing);

        });
        if(nMissing < k) {
            currentItem += (k - nMissing);
            return currentItem;
        }
        System.out.println();
        System.out.println("al:" + al);
        return currentItem;
    }

    public static void main(String[] args) {
        MissingKInteger missingKInteger = new MissingKInteger();
        // [1,3] k=1 ans = 2
        // [ 2,3,4,7,11 ] k=5 ans = 9
        // { 2,3,4,7,11 } k= ans = 
        
        int[] arr = new int[] { 3,10 };
        int k = 2;
        System.out.println("input arr is:" + Arrays.toString(arr));
        System.out.println("find " + k + "-th integer");

        int ans = missingKInteger.findKthPositive(arr, k);
        System.out.println(k + "-th integer:" + ans);
    }
Run Code Online (Sandbox Code Playgroud)

输出是:

input arr is:[3, 10]
        find 2-th integer
        --- examine x 3 ---
        loop. currentItem 1, nMissing 1
        loop. currentItem 2, nMissing 2
        returning nMissing: 2--- examine x 10 ---
        loop. currentItem 3, nMissing 3
        loop. currentItem 4, nMissing 4
        loop. currentItem 5, nMissing 5
        loop. currentItem 6, nMissing 6
        loop. currentItem 7, nMissing 7
        loop. currentItem 8, nMissing 8
        loop. currentItem 9, nMissing 9
        out of loop. currentItem 10, nMissing 9

        al:[1, 2, 3, 4, 5, 6, 7, 8, 9]
        2-th integer:10
Run Code Online (Sandbox Code Playgroud)

背景:

我正在尝试使用 Java 8 Streams解决第 k 个缺失整数的问题

给定一个按严格递增顺序排序的正整数数组 arr 和一个整数 k。

查找此数组中缺少的第 k 个正整数。

示例 1:

输入:arr = [2,3,4,7,11], k = 5 输出:9 解释:缺少的正整数是 [1,5,6,8,9,10,12,13,...] . 第 5 个缺失的正整数是 9。

示例 2:

输入:arr = [1,2,3,4], k = 2 输出:6 解释:缺少的正整数是 [5,6,7,...]。第二个缺失的正整数是 6。

当然,迭代解决方案是

class Solution {

    public int findKthPositive(int[] arr, int k) {
        int currentItem = 0;
        int nMissing = 0;

        for(int x : arr) {
            if (x - currentItem == 1) { // if it is the next consecutive number e.g. 2,3,4,5... then is is not a candidate
                currentItem++;
            } else { // there is a gap here. get all the numbers in the gap
                endLoop: do {
                    nMissing++; // increment count of missing numbers
                    currentItem++; // yes, this is a missing number
                    if(nMissing == k) { // found the nth missing, stop here
                        return currentItem;             
                    }
                } while (x - currentItem > 1); // while there is a gap
                currentItem = x;
            }
        };
        if(nMissing < k) { // if input array atopped short, then generate remaining missing numbers.
            currentItem += (k - nMissing);
        }
        return currentItem;
    }
}
Run Code Online (Sandbox Code Playgroud)

Oli*_*ver 5

因为returninStream.forEach或inIterable.forEachcontinuein 传统 for 循环或 for each 循环实际上是同义词。请记住,正在流中的每个元素调用作为参数的方法(无论是否匿名)。return正在返回该方法,而不是调用您的方法的方法。例如:

IntStream.range(0, 5).forEach(i -> {
  if(i == 3) return;

  System.out.print(i);
}
Run Code Online (Sandbox Code Playgroud)

将打印:

0124
Run Code Online (Sandbox Code Playgroud)