合并和从Java中的多个列表中删除重复项的最佳方法 [英] Best way to merge and remove duplicates from multiple lists in Java

查看:246
本文介绍了合并和从Java中的多个列表中删除重复项的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的情况是我将收到2个以上的ArrayList<Widget>,并且我需要能够合并所有列表并删除所有重复的Widget,以便最后只剩下1个包含所有<来自所有合并列表的c1>,但没有重复项.

I have a situation where I will be receiving 2+ ArrayList<Widget> and I need to be able to merge all the lists and remove any duplicate Widget so that I wind up with only 1 ArrayList<Widget> that contains all Widgets from all the merged lists, but without any duplicates.

假设Widget具有重写的equals方法,可以使用 来确定两个Widget是否重复,尽管可能有更好的方法:

Assume Widget has an overridden equals method that can be used for determining whether two Widgets are duplicates, although there may be a better way:

public ArrayList<Widget> mergeAndRemoveDupes(ArrayList<Widget> widgets...) {
    // ???
}

寻找最有效的算法来完成此任务.我很高兴使用Apache Commons或任何其他对我也有帮助的开源库!预先感谢!

Looking for the most algorithmically efficient way of accomplishing this. I am happy to use Apache Commons or any other open source libs that would help me out too! Thanks in advance!

推荐答案

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

For each ArrayList<Widget>, add each element to a Set<Widget> (HashSet or TreeSet, depending on whether they can be ordered in some way, or are hashable) utilizing addAll. Sets contain no duplicates by default.

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

You can convert this Set back into an (Array)List if you need to at the end.

请注意,如果您决定使用HashSet,则需要为Widget类实现hashCode,但是,如果您有覆盖的equals,,则仍然应该这样做.

Note you will need to implement hashCode for your Widget class if you decide to use a HashSet, but if you have an overridden equals, you should do this anyway.

这是一个示例:

//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但不想在Widget类上实现Comparable<T>,则可以给集合本身一个Comparator对象:

If you want to use a TreeSet but don't want to implement Comparable<T> on your Widget class, you can give the set itself a Comparator object:

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());
            }
           });

这篇关于合并和从Java中的多个列表中删除重复项的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆