假设我有一个int数组,我想找到总和为零的所有对。在过去,我会做这样的事情:
public static int count(int[] a) {
int cnt = 0;
int N = a.length;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (a[i] + a[j] == 0) {
cnt++;
}
}
}
return cnt;
}
现在我在将此转换为流时遇到了一些麻烦。
我尝试了以下方法,但是我收到了IllegalStateException:
final IntStream stream1 = Arrays.stream(a);
final IntStream stream2 = Arrays.stream(a);
long res = stream1.flatMap(i -> stream2.filter(j -> (j + i == 0))).count();
答案 0 :(得分:5)
将stream2.filter
更改为Arrays.stream(a)
- 第二次尝试处理时,Stream会关闭。
但无论如何你都算不上,应该是:
IntStream.range(0, a.length)
.flatMap(x -> Arrays.stream(a).skip(x + 1).filter(j -> j + a[x] == 0))
.count();
答案 1 :(得分:5)
Streams
不可重复使用,因此您无法定义一次并继续重复使用。这就是将它们存储在变量中被认为是一种不好的做法。
您需要在现场创建它们:
long res = Arrays.stream(a)
.flatMap(i -> Arrays.stream(a).filter(j -> (j + i == 0)))
.count();
此外,为了完全反映所提供的实现并避免重复,您需要skip
每个嵌套Stream
开头的一些元素:
long res = IntStream.range(0, a.length)
.flatMap(i -> Arrays.stream(a).skip(i + 1).filter(j -> (j + a[i] == 0)))
.count();
如果要将它们提取到变量,则需要使用Supplier
作为Streams
的工厂。每个get
调用都会创建一个新的Stream
实例:
final Supplier<IntStream> s = () -> Arrays.stream(a);
long res = s.get()
.flatMap(i -> s.get().filter(j -> (j + i == 0)))
.count();