如何将嵌套循环转换为嵌套Streams?

MLe*_*ria 3 java arrays java-8 java-stream

假设我有一个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;
    }
Run Code Online (Sandbox Code Playgroud)

现在我在将此转换为流时遇到了一些麻烦.

我尝试了以下方法但是我收到了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();
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 6

更改stream2.filterArrays.stream(a)- 第二次尝试处理时,Stream将关闭.

但无论如何你都没有正确计算,它应该是:

 IntStream.range(0, a.length)
          .flatMap(x -> Arrays.stream(a).skip(x + 1).filter(j -> j + a[x] == 0))
          .count();
Run Code Online (Sandbox Code Playgroud)


Grz*_*rek 5

Streams不可重复使用,因此您无法定义它们并继续重复使用.这就是将它们存储在变量中被认为是一种不好的做法.

您需要在现场创建它们:

long res = Arrays.stream(a)
  .flatMap(i -> Arrays.stream(a).filter(j -> (j + i == 0)))
  .count();
Run Code Online (Sandbox Code Playgroud)

另外,为了完全反映所提供的实现并避免重复,您需要skip在每个嵌套的开头使用一些元素Stream:

long res = IntStream.range(0, a.length)
  .flatMap(i -> Arrays.stream(a).skip(i + 1).filter(j -> (j + a[i] == 0)))
  .count();
Run Code Online (Sandbox Code Playgroud)

如果你想将它们提取到变量,你需要使用一个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();
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

545 次

最近记录:

8 年,8 月 前