【发布时间】:2019-05-26 20:10:37
【问题描述】:
这个问题是在forEach 的上下文中提出的。
评论(在接受答案后):我接受了@nullpointer 的答案,但它仅在我的代码示例的上下文中是正确的,而不是在关于reduce 可破坏性的一般问题中。 .
问题:
但是reduce 或collect 中是否有一种方法可以过早地“中断”,而无需遍历所有流元素? (这意味着我需要在迭代时累积状态,所以我使用reduce 或collect)。
简而言之:我需要迭代流的所有元素(元素是整数并且从小到大排序),但是查看 2 个相邻元素并比较它们,如果它们之间的差异大于 1,我需要“中断”并停止“累积状态”,我需要返回最后传递的元素。
抛出 RuntimeException 的变体和传递外部状态的变体 - 对我不利。
使用 cmets 的代码示例:
public class Solution {
public int solution(int[] A) {
Supplier<int[]> supplier = new Supplier<int[]>() {
@Override
public int[] get() {
//the array describes the accumulated state:
//first element in the array , if set > 0, means - the result is achieved, we can stop iterate over the rest elements
//second element in the array will represent the "previous element" while iterating the stream
return new int[]{0, 0};
}
};
//the array in accumulator describes the accumulated state:
//first element in the array , if set > 0, means - the result is achieved, we can stop iterate over the rest elements
//second element in the array will represent the "previous element" while iterating the stream
ObjIntConsumer<int[]> accumulator = new ObjIntConsumer<int[]>() {
@Override
public void accept(int[] sett, int value) {
if (sett[0] > 0) {
;//do nothing, result is set
} else {
if (sett[1] > 0) {//previous element exists
if (sett[1] + 1 < value) {
sett[0] = sett[1] + 1;
} else {
sett[1] = value;
}
} else {
sett[1] = value;
}
}
}
};
BiConsumer<int[], int[]> combiner = new BiConsumer<int[], int[]>() {
@Override
public void accept(int[] sett1, int[] sett2) {
System.out.println("Combiner is not used, we are in sequence");
}
};
int result[] = Arrays.stream(A).sorted().filter(value -> value > 0).collect(supplier, accumulator, combiner);
return result[0];
}
/**
* We have an input array
* We need order it, filter out all elements that <=0 (to have only positive)
* We need find a first minimal integer that does not exist in the array
* In this example it is 5
* Because 4,6,16,32,67 positive integers array is having 5 like a minimum that not in the array (between 4 and 6)
*
* @param args
*/
public static void main(String[] args) {
int[] a = new int[]{-2, 4, 6, 16, -7, 0, 0, 0, 32, 67};
Solution s = new Solution();
System.out.println("The value is " + s.solution(a));
}
}
【问题讨论】:
-
你能详细说明一下,“累积状态”是什么意思,我需要返回最后传递的元素
-
并非所有循环都最好用流替换。如果你有这样的行为,它可能会更清楚地作为一个循环(即使有某种方法可以让 Stream 做你想做的事)
-
添加代码示例
标签: java java-8 java-stream reduce collect