簡體   English   中英

如何在列表中查找重復項以合並它們

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM