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

时间:2018-11-16 23:28:18

标签: 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()向数组添加另一个项目。但是,我试图使用精美的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(...)中实现它。还是有一种更清洁的方法?

1 个答案:

答案 0 :(得分:3)

您可以使用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);
相关问题