Reputation: 3735
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;
}
}
Upvotes: 0
Views: 126
Reputation: 503
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
Upvotes: 5