`Stream.forEach()` 中的 `return;` 是用来跳出循环控制的吗?

huangapple go评论72阅读模式
英文:

Where does `return;` in Stream.forEach() break control to?

问题

Stream.forEach() 中的 return; 跳转到哪里?

我预期在此语句打印后,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("--- 检查 x %d ---\n", x);
            if (x - currentItem == 1) {
                currentItem++;
                System.out.format("步骤。currentItem %d, nMissing %d\n", currentItem, nMissing);
            } else {
                do {
                    nMissing++;
                    currentItem++;
                    al.add(currentItem);
                    System.out.format("循环。currentItem %d, nMissing %d\n", currentItem, nMissing);
                    if(nMissing == k) {
                        System.out.format("返回 nMissing: %d" , nMissing);
                        return;				
                    }
                } while (x - currentItem > 1);
                currentItem = x;
            }
            System.out.format("循环结束。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();

        int[] arr = new int[] { 3, 10 };
        int k = 2;
        System.out.println("输入数组为:" + Arrays.toString(arr));
        System.out.println("查找第 " + k + " 个整数");

        int ans = missingKInteger.findKthPositive(arr, k);
        System.out.println(k + " 个整数:" + ans);
    }
}

输出为:

输入数组为:[3, 10]
查找第 2 个整数
--- 检查 x 3 ---
循环。currentItem 1, nMissing 1
循环。currentItem 2, nMissing 2
返回 nMissing: 2--- 检查 x 10 ---
循环。currentItem 3, nMissing 3
循环。currentItem 4, nMissing 4
循环。currentItem 5, nMissing 5
循环。currentItem 6, nMissing 6
循环。currentItem 7, nMissing 7
循环。currentItem 8, nMissing 8
循环。currentItem 9, nMissing 9
循环结束。currentItem 10, nMissing 9
al:[1, 2, 3, 4, 5, 6, 7, 8, 9]
2 个整数:10

背景:

我正在尝试使用 Java 8 的流解决 此 k-th 缺失正整数问题

> 给定严格递增顺序的正整数数组 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,...]。第 2 个缺失的正整数是 6。

当然,迭代解决方案可以是:

class Solution {

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

        for (int x : arr) {
            if (x - currentItem == 1) { // 如果是下一个连续的数字,例如 2,3,4,5...,则不是候选项
                currentItem++;
            } else { // 这里有一个间隙。获取间隙中的所有数字
                endLoop: do {
                    nMissing++; // 增加缺失数字的计数
                    currentItem++; // 是缺失的数字
                    if (nMissing == k) { // 找到第 n 个缺失的数字,停止
                        return currentItem;
                    }
                } while (x - currentItem > 1); // 当有间隙时
                currentItem = x;
            }
        };
        if (nMissing < k) { // 如果输入数组停止,然后生成剩余的缺失数字。
            currentItem += (k - nMissing);
        }
        return currentItem;
    }
}

注意:上述内容只包含翻译后的部分,没有其他额外的内容。

英文:

Where does return; in Stream.forEach() break control to?

I expected after this statement was printed, that the forEach would be exited and into the rest of the method.

> returning nMissing: 2

But instead, I find that instead it goes back to process the rest of the stream.

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&lt;Integer&gt; al = new ArrayList&lt;Integer&gt;();
public int findKthPositive(int[] arr, int k) {
Arrays.stream(arr).forEach(x -&gt; {
System.out.format(&quot;--- examine x %d ---\n&quot;, x);
if (x - currentItem == 1) {
currentItem++;
System.out.format(&quot;step. currentItem %d, nMissing %d\n&quot;, currentItem, nMissing);
} else {
do {
nMissing++;
currentItem++;
al.add(currentItem);
System.out.format(&quot;loop. currentItem %d, nMissing %d\n&quot;, currentItem, nMissing);
if(nMissing == k) {
System.out.format(&quot;returning nMissing: %d&quot; , nMissing);
return;				
}
} while (x - currentItem &gt; 1);
currentItem = x;
}
System.out.format(&quot;out of loop. currentItem %d, nMissing %d\n&quot;, currentItem, nMissing);
});
if(nMissing &lt; k) {
currentItem += (k - nMissing);
return currentItem;
}
System.out.println();
System.out.println(&quot;al:&quot; + 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(&quot;input arr is:&quot; + Arrays.toString(arr));
System.out.println(&quot;find &quot; + k + &quot;-th integer&quot;);
int ans = missingKInteger.findKthPositive(arr, k);
System.out.println(k + &quot;-th integer:&quot; + ans);
}

Output is:

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

background:

I am trying to solve this problem of the k-th missing integer using Java 8 Streams.

> Given an array arr of positive integers sorted in a strictly
> increasing order, and an integer k.
>
> Find the kth positive integer that is missing from this array.
>
>
>
> Example 1:
>
> Input: arr = [2,3,4,7,11], k = 5 Output: 9 Explanation: The missing
> positive integers are [1,5,6,8,9,10,12,13,...]. The 5th missing
> positive integer is 9.

> Example 2:
>
> Input: arr = [1,2,3,4], k = 2 Output: 6 Explanation: The missing
> positive integers are [5,6,7,...]. The 2nd missing positive integer is
> 6.

of course, an iterative solution would be

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 &gt; 1); // while there is a gap
currentItem = x;
}
};
if(nMissing &lt; k) { // if input array atopped short, then generate remaining missing numbers.
currentItem += (k - nMissing);
}
return currentItem;
}
}

答案1

得分: 5

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

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

将打印:

0124
英文:

Because return in Stream.forEach or Iterable.forEach is effectively synonymous to continue in traditional for loops or for each loops. Remember that the method (whether anonymous or not) that is your argument, is being called for each element in the stream. return is returning that method, not the method calling your method. For example:

IntStream.range(0, 5).forEach(i -&gt; {
if(i == 3) return;
System.out.print(i);
}

Will print:

0124

huangapple
  • 本文由 发表于 2020年8月10日 09:20:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63332939.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定