![](/img/trans.png)
[英]Java Comparing object Lists to find duplicates and putting them in a new list
[英]How to find duplicates in a List to merge them
我有一個潛在重復的列表。 我通過他們的 ID 識別重復項。 這些對象有孩子,現在我想合並重復項,以便孩子只附加到一個 object。 我如何最好地識別重復項,也許是流?
public class Foo {
private String id;
private Collection<String> childs;
}
private Collection<Foo> mergeDuplicates(Collection<Foo> fooList) {
/*this method should call the mergeChilds on found Duplicates,
and return the processed Collection of Foos*/
}
private Foo mergeChilds(Foo foo1, Foo foo2) {
...
}
您可以根據id
將它們收集到Map
並使用mergeFunction
合並children
項。 然后 map 將它們返回為最終對象:
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
}
在相同的 class 中實現了更新的mergeChildren
方法:
private Collection<String> mergeChildren(Collection<String> foo1Children, Collection<String> foo2Children) {
foo1Children.addAll(foo2Children);
return foo1Children;
}
注意: mergeFunction ( (a,b) -> {...}
) 僅在識別出基於id
的重復項時才執行。
Map 並重新接線孩子:
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。 或子對象也是父對象,需要第二次步行才能從子對象中刪除過時的對象(未出現在地圖中)。
這是您的用例的詳細示例,希望對您有所幫助。 這使用流找到重復項,然后使用 append 找到現有 object 的子代。
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() + "]";
}
}
您可以在此處運行並檢查結果https://onecompiler.com/java/3v2sj7qyb
結果:
[Pojo [id=a, children=[c1, c2, c3, c4]], Pojo [id=b, children=[c5, c6]]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.