Java 深入比较数组中的每个元素
我有以下3个文件 A.java:Java 深入比较数组中的每个元素,java,java-8,java-stream,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
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;
}
}
这就是我期望它做的,即如果两个元素从A.getB()
返回相同的浮点值,则使用b
的一半向数组中添加另一项。然而,我试图使用花哨的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;
});
这个输出:
用3.0检查3.0
用5.0检查3.0
用3.0检查3.0
用3.0检查5.0
用5.0检查5.0
用3.0检查5.0
用3.0检查3.0
用5.0检查3.0
用3.0检查3.0
正如你所看到的,这遵循了O(n²)算法,这不是我想要的。在我的原始代码中,我“跳过”了我已经使用外部嵌套for循环的索引检查过的元素。所以我的问题是,在我尝试的嵌套
.anyMatch(…)
中,是否有某种方法可以实现这一点。或者有更干净的方法吗?您可以使用流API复制replicate
方法,如下所示:
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);
流结果=
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->newa(d[cur].getB()*0.5f));
d=Stream.concat(Arrays.Stream(d),result)
.toArray(A[]::新的);
您是否尝试使用streams API复制复制
方法?具有相同的时间复杂度还是更好?@Aomineduplicate
只是我随机想到的方法名称,所以不。不谈方法名称,我想问的是复制方法的逻辑是你试图复制的吗?或者您只是想改进代码片段Arrays.stream(d).anyMatch(cur->{………
?@Aomine啊,好吧,对不起,我误解了。所以,是的,这是正确的,我正在尝试复制最后一个代码段上的duplicate
方法中的逻辑。我的第一个问题或第二个问题…?谢谢。你能简要解释一下IntStream.range(cur+1,d.length)的用途吗
是吗?它只是从cur+1
到d.length
独占生成一个IntStream
数字,也就是说,就像在你的代码中为(intnxt=cur+1;nxt
@newbie>生成的一样
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);