java - 深入比较数组中的每个元素

标签 java java-8 java-stream

我有以下3个文件,

A.java:

class A {

    private float b;    

    public A(float b) {
        this.b = b;
    }

    public float getB() {
        return b;
    }

    public String toString() {
        return "A(b = " + b + ")";    
    }

}

C.java:

import java.util.Arrays;

class C {

    private A[] d;
    private int i = 0;

    public C() {
        d = new A[5];
    }

    public void addB(A b) {
        d[i++] = b;
    }

    public String toString() {
        return "C(b = " + Arrays.toString(d) + ")";    
    }

    public void duplicate() {
        A temp[] = Arrays.copyOf(d, d.length);
        for (int cur = 0; cur < d.length; cur++) {
            if (d[cur] == null) continue;
            float currB = d[cur].getB();
            for (int nxt = cur + 1; nxt < d.length; nxt++) {
                if(d[nxt] == null) continue;
                if(currB == d[nxt].getB()) {
                    temp[i++] = new A(currB * 0.5f);
                }
            }
        }
        d = temp;
    }
}

D.java:

class D {

    public static void main(String[] args) {
        C c = new C();
        c.addB(new A(3));
        c.addB(new A(5));
        c.addB(new A(3));
        System.out.println(c.toString()); // C(b = [A(b = 3.0), A(b = 5.0), A(b = 3.0), null, null])
        c.duplicate();
        System.out.println(c.toString()); // C(b = [A(b = 3.0), A(b = 5.0), A(b = 3.0), A(b = 1.5), null])

    }

}

这符合我的预期,即用一半的 b 将另一个项目添加到数组中如果两个元素从 A.getB() 返回相同的 float .但是,我尝试使用花哨的 Java 8 流方法和 lambda 函数来实现它,如下所示:

Arrays.stream(d).anyMatch(cur -> {
    if (cur == null) return false;
    Arrays.stream(d).anyMatch(nxt -> {
        if (nxt == null) return false;
        System.out.println("Checking " + cur.getB() + " with " + nxt.getB());
        return false;
    });
    return false;
});

这输出:

Checking 3.0 with 3.0 Checking 3.0 with 5.0 Checking 3.0 with 3.0 Checking 5.0 with 3.0 Checking 5.0 with 5.0 Checking 5.0 with 3.0 Checking 3.0 with 3.0 Checking 3.0 with 5.0 Checking 3.0 with 3.0

如您所见,这遵循 O(n²) 算法,这不是我想要的。在我的原始代码中,我“跳过”了我已经使用外部嵌套 for 循环中的索引检查过的元素。所以我的问题是,是否有办法在嵌套的 <Stream>.anyMatch(...) 中以某种方式实现它?我尝试过。或者有更简洁的方法吗?

最佳答案

您可以使用 Stream API 复制 duplicate 方法,如下所示:

Stream<A> result = 
       IntStream.range(0, d.length)
                .filter(cur -> d[cur] != null)
                .flatMap(cur -> IntStream.range(cur + 1, d.length)
                        .filter(nxt -> d[nxt] != null)
                        .filter(nxt -> d[cur].getB() == d[nxt].getB())
                        .map(i -> cur))
                .mapToObj(cur -> new A(d[cur].getB() * 0.5f));

d = Stream.concat(Arrays.stream(d), result)
          .toArray(A[]::new);

关于java - 深入比较数组中的每个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53346688/

相关文章:

java - Eclipse 自动完成参数类型强调

java - CompletableFuture 和 CountDownLatch 超时

java - 我可以在 Java 8 中复制流吗?

java - 将增强循环转换为 Java 8 Streams,过滤器 - forEach

java - Java 8 向前兼容 Java 11 吗?

Java编译问题,Linux,Eclipse项目在Linux上重新编译

java - 测试我的简单 HTTPS 服务器的客户端

Java 8 嵌套循环流

Java lambda 交集两个列表并从结果中删除

java - 如何向现有 Java 8 流添加单个 Key 值?