gpt4 book ai didi

java - 如何以一种好的方式在 Java 中的同一个列表中查找对象对

转载 作者:行者123 更新时间:2023-12-04 11:56:37 24 4
gpt4 key购买 nike

初始化

我有一个包含不同对象的 ArrayList。我试图根据条件搜索相同的列表对象对。如果我找到正确的配对,我将创建一个新对象并将其添加到新列表中。但是我想避免在 objectA 与 objectB 配对以及 objectB 与 objectA 配对时创建一个对象对。

直到现在我还没有找到一个好的方法来做到这一点。

我尝试过的想法

2 个 for 循环

for(Object objectA : objectList){
for(Object objectB : objectList){
if(condition){
// create new object
// add to list
}
}
}

问题:我需要有点标记已经匹配的对,否则它会导致我想避免为同一对创建两个对象。它有效,但可能不是最佳解决方案?

迭代器

与带有两个 forloop 的版本一样,我使用了一个迭代器并从列表中删除了已经匹配的对象对。有效但似乎不太好?

Java8 forEach 和 removeIf

objectList.stream().forEach(posA -> {
objectList.removeIf(posB -> condition);
});

问题:我什么时候创建我的对象对对象...?

问题

哪个是最好的主意 - 或者有没有更好的解决方案?

最佳答案

显然,您考虑的是一个无序对,其中 pair(a,b) 与 pair(b,a) 相同。您必须自己为此目的创建一个类,例如

class Pair<T> {
final T a, b;

public Pair(T a, T b) {
this.a = a;
this.b = b;
}
@Override
public boolean equals(Object obj) {
if(obj==this) return true;
if(!(obj instanceof Pair)) return false;
Pair<?> p=(Pair<?>)obj;
return Objects.equals(this.a, p.a) && Objects.equals(this.b, p.b)
|| Objects.equals(this.a, p.b) && Objects.equals(this.b, p.a);
}

@Override
public int hashCode() {
return Objects.hashCode(a) + Objects.hashCode(b);
}
}

有了一个带有所需语义的类,您可以简单地创建所有组合并让 Stream API 删除重复项。如果源列表已经有重复项,这甚至会起作用:

List<YourNewObjectType> result = objectList.stream()
.flatMap(objA -> objectList.stream().map(objB -> new Pair<>(objA,objB)))
.distinct()
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … )
.collect(Collectors.toList());

您没有指定是否允许元素与自身配对。如果不是,您可以过滤掉这些情况:

List<YourNewObjectType> result = objectList.stream()
.flatMap(objA -> objectList.stream()
.filter(objB -> !Objects.equals(objA, objB))
.map(objB -> new Pair<>(objA,objB)))
.distinct()
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … )
.collect(Collectors.toList());

作为旁注,如果您的结果类型的构造没有副作用且成本不高,并且该类型具有反射(reflect)两个输入元素的相等性,您可以考虑构造它们而不是 Pair 实例并为它们使用 .distinct,保存 Pair 实例到 YourNewObjectType 实例的转换。

如果您的源列表没有重复项,您可以利用这些知识根据索引构建唯一对:

List<YourNewObjectType> result = IntStream.range(0, objectList.size())
.mapToObj(i -> IntStream.range(i/*+1*/, objectList.size())
.mapToObj(j -> new Pair<>(objectList.get(i),objectList.get(j))))
.flatMap(Function.identity())
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … */)
.collect(Collectors.toList());

如果不允许将元素与其自身配对,只需将 /*+ 1*/ 注释变为真正的 +1。此代码的可读性较差,但可能更高效。

关于java - 如何以一种好的方式在 Java 中的同一个列表中查找对象对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39345168/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com