从Java中的多个列表合并和删除重复项的最佳方法

时间:2013-05-09 02:12:49

标签: java performance algorithm list merge

我的情况是,我将收到2 + ArrayList<Widget>并且我需要能够合并所有列表并移除任何重复的Widget,这样我最终只能获得{{1} {{1}包含所有合并列表中的所有ArrayList<Widget>,但没有任何重复项。

假设Widget有一个被覆盖的Widget方法,可以用于确定两个equals是否重复,尽管可能有更好的方法:

Widget

寻找实现此目标的最具算法效率的方法。我很高兴使用Apache Commons或其他任何可以帮助我的开源库!提前谢谢!

3 个答案:

答案 0 :(得分:11)

对于每个ArrayList<Widget>,将每个元素添加到Set<Widget>HashSetTreeSet,具体取决于它们是否可以某种方式订购,或者是否可以使用addAll。默认情况下,集合不包含重复项。

如果您需要,可以将此Set转换回(Array)List

请注意,如果您决定使用hashCode,则需要为Widget课程实施HashSet,但如果您有被覆盖的equals,,则无论如何都应该这样做

编辑:这是一个例子:

//Either the class itself needs to implement Comparable<T>, or a similar
//Comparable instance needs to be passed into a TreeSet 
public class Widget implements Comparable<Widget>
{
    private final String name;
    private final int id;

    Widget(String n, int i)
    {
        name = n;
        id = i;
    }

    public String getName()
    {
        return name;
    }

    public int getId()
    {
        return id;
    }

    //Something like this already exists in your class
    @Override
    public boolean equals(Object o)
    {
        if(o != null && (o instanceof Widget)) {
            return ((Widget)o).getName().equals(name) &&
                   ((Widget)o).getId() == id;
        }
        return false;
    }

    //This is required for HashSet
    //Note that if you override equals, you should override this
    //as well. See: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java
    @Override 
    public int hashCode()
    {
        return ((Integer)id).hashCode() + name.hashCode();
    }

    //This is required for TreeSet
    @Override
    public int compareTo(Widget w)
    {
        if(id < w.getId()) return -1;
        else if(id > w.getId()) return 1;
        return name.compareTo(w.getName());
    }

    @Override 
    public String toString()
    {
        return "Widget: " + name + ", id: " + id;
    }
}

如果您想使用TreeSet但又不想在Comparable<T>课程上实施Widget,则可以为该集合提供Comparator个对象:< / p>

private Set<Widget> treeSet;
....
treeSet = new TreeSet<Widget>(new Comparator<Widget>() {
            public int compare(Widget w1, Widget w2)
            {
                if(w1.getId() < w2.getId()) return -1;
                else if(w1.getId() > w2.getId()) return 1;
                return w1.getName().compareTo(w2.getName());
            }
           });

答案 1 :(得分:8)

我会这样做

Set<Widget> set = new HashSet<>(list1);
set.addAll(list2);
List<Widget> mergeList = new ArrayList<>(set);

答案 2 :(得分:2)

使用Set集合类,

ArrayList<Widget> mergeList = new ArrayList<widget>();
mergeList.addAll(widgets1);
mergeList.addAll(widgets2);
Set<Widget> set  = new HashSet<Widget>(mergeList);
ArrayList<Widget> mergeListWithoutDuplicates = new ArrayList<widget>();
mergeListWithoutDuplicates .addAll(set);
return mergeListWithoutDuplicates;

现在,Set将删除ArrayList中的所有重复值。