如何在列表中查找重复项并合并它们

我有一个可能重复的列表。我通过 ID 识别重复项。这些对象有子对象,现在我想合并重复项,以便子对象仅附加到一个对象。我如何最好地识别重复项,也许是通过流?


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) {

    ...

  }


慕森卡
浏览 117回答 3
3回答

炎炎设计

您可以将它们收集到Map基于id并children使用合并mergeFunction。然后将它们映射回最终对象,如下所示:private Collection<Foo> mergeDuplicates(Collection<Foo> fooCollection) {&nbsp; &nbsp; return fooCollection.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Foo::getId, Foo::getChildren, this::mergeChildren))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .entrySet().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(e -> new Foo(e.getKey(), e.getValue()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toCollection(ArrayList::new)); // collect accordingly}更新后的mergeChildren方法在同一个类中实现:private Collection<String> mergeChildren(Collection<String> foo1Children, Collection<String> foo2Children) {&nbsp; &nbsp; foo1Children.addAll(foo2Children);&nbsp; &nbsp; return foo1Children;}注意:仅当识别出基于的重复项时才执行mergeFunction ( )。(a,b) -> {...}id

慕运维8079593

映射并重新连接子级:List<Obj> list = ...;Map<Long, Obj> objectsById = new HashMap<>();list.forEach(obj -> {&nbsp; &nbsp; objectsById.merge(obj.getId(), obj,&nbsp; &nbsp; &nbsp; &nbsp; (oldv, v) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (oldv != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v.getChildren().forEach(ch -> ch.setParent(oldv));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return oldv;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return v;&nbsp; &nbsp; });});list = objectsById.values();如果只有 getParent,没有 getChildren。或者子对象也是父对象,则需要进行第二次行走以从子对象中删除过时的对象(未出现在地图中)。

扬帆大鱼

这是针对您的用例的详细示例,希望对您有所帮助。这使用流查找重复项,然后将子项附加到现有对象。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]]]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java