对于EachRemaining,有没有更好的方法来终止迭代器



我编写了以下代码

List<Integer> ll = new ArrayList<>();
numbers.forEach(n1 -> {
numbers.iterator().forEachRemaining((Consumer<? super Integer>) n2 -> {
numbers.iterator().forEachRemaining((Consumer<? super Integer>) n3 -> {
if (n1 + n2 + n3 == 1234)
ll.addAll(Arrays.asList(n1,n2,n3));
throw new RuntimeException("elements found");
});
});
});

我试图在一个数组中找到3个元素,它们构成了1234的和。有没有更好的方法,终止EachRemaining的最后一个?是否有更好的解决方案,使用流Api,而不使用三个for循环(i,j,k(

编辑:因为我得到了很多反馈,所以这段代码只是为了教育目的(更好地理解流和迭代器(。这不是解决问题的方法(在一个数组中找到三个构建1234总和的元素(。我以为forEachRemaining可以防止数组中元素的重复和——我错了,吸取了教训。

如果你必须使用流来解决它(我认为这只是出于教育目的(,你必须通过索引而不是元素进行流。否则,重复的元素会作为错误的结果泄漏,正如我在有问题的评论中所示。

public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(34);
numbers.add(600);
numbers.add(600);
int[] result = IntStream.range(0, numbers.size()).boxed()
.flatMap(first -> IntStream.range(0, numbers.size()).filter(second -> second != first).boxed()
.flatMap(second -> IntStream.range(0, numbers.size()).filter(third -> third != second && third != first).boxed()
.map(third -> new int[] {numbers.get(first), numbers.get(second), numbers.get(third)})
.filter(arr -> IntStream.of(arr).sum() == 1234)
)
)
.findFirst()
.orElse(null);
System.out.println(Arrays.toString(result));        
}

每个建议您使用纯旧for循环的人(无论违反了什么SO规则(都是正确的。只需使用它。流是一个强大的概念,但用于不同于您的任务类型。

像一样

List<Integer> doYourThingWith(List<Integer> numbers) {
for (Integer n1 : numbers) {
for (Integer n2 : numbers) {
for (Integer n3 : numbers) {
if (yourConditionIsTrue) return Arrays.asList(n1, n2, n3);
}
}
}
return null;
}
....
List<Integer> result=doYourThingWith(yourSetOfNumbers);

你可以这样做:

List<Integer> ll = numbers.stream()
.flatMap(a -> numbers.stream()
.flatMap(b -> numbers.stream()
.filter(c -> a + b + c == 1234)
.map(c -> Arrays.asList(a, b, c))
)
)
.findFirst()
.orElse(Collections.emptyList());

最新更新