3 回答
TA贡献1808条经验 获得超4个赞
您可以将它们收集到Map基于id并children使用合并mergeFunction。然后将它们映射回最终对象,如下所示:
private Collection<Foo> mergeDuplicates(Collection<Foo> fooCollection) {
return fooCollection.stream()
.collect(Collectors.toMap(Foo::getId, Foo::getChildren, this::mergeChildren))
.entrySet().stream()
.map(e -> new Foo(e.getKey(), e.getValue()))
.collect(Collectors.toCollection(ArrayList::new)); // collect accordingly
}
更新后的mergeChildren方法在同一个类中实现:
private Collection<String> mergeChildren(Collection<String> foo1Children, Collection<String> foo2Children) {
foo1Children.addAll(foo2Children);
return foo1Children;
}
注意:仅当识别出基于的重复项时才执行mergeFunction ( )。(a,b) -> {...}id
TA贡献1876条经验 获得超5个赞
映射并重新连接子级:
List<Obj> list = ...;
Map<Long, Obj> objectsById = new HashMap<>();
list.forEach(obj -> {
objectsById.merge(obj.getId(), obj,
(oldv, v) -> {
if (oldv != null) {
v.getChildren().forEach(ch -> ch.setParent(oldv));
return oldv;
}
return v;
});
});
list = objectsById.values();
如果只有 getParent,没有 getChildren。或者子对象也是父对象,则需要进行第二次行走以从子对象中删除过时的对象(未出现在地图中)。
TA贡献1799条经验 获得超9个赞
这是针对您的用例的详细示例,希望对您有所帮助。这使用流查找重复项,然后将子项附加到现有对象。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class HelloWorld {
public static void main(String[] args) {
Pojo p1 = new Pojo("a", new ArrayList<String>(Arrays.asList("c1", "c2")));
Pojo p2 = new Pojo("a", new ArrayList<String>(Arrays.asList("c3", "c4")));
Pojo p3 = new Pojo("b", new ArrayList<String>(Arrays.asList("c5", "c6")));
List<Pojo> pojos = new ArrayList<Pojo>();
pojos.add(p1);
pojos.add(p2);
pojos.add(p3);
Set<Pojo> uniquePojos = new HashSet<>();
pojos.stream().filter(p -> {
boolean notExists = uniquePojos.add(p);
if (!notExists) {
for (Pojo up : uniquePojos) {
if (up.equals(p)) {
up.children.addAll(p.children);
}
}
}
return notExists;
}).collect(Collectors.toList());
System.out.println(uniquePojos);
}
}
class Pojo {
Pojo(String id, List<String> children) {
this.id = id;
this.children = children;
}
String id;
List<String> children;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pojo other = (Pojo) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return "Pojo [id=" + id + ", children=" + children.toString() + "]";
}
}
结果:
[Pojo [id=a, children=[c1, c2, c3, c4]], Pojo [id=b, children=[c5, c6]]]
添加回答
举报