英文:
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<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);
}
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 > 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;
}
}
答案1
得分: 5
因为Stream.forEach
或Iterable.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 -> {
if(i == 3) return;
System.out.print(i);
}
Will print:
0124
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论