11

2+ を受け取る状況があり、ArrayList<Widget>すべてのリストをマージして重複を削除できるようにする必要があるため、マージされたすべてのリストからのすべての sを含むが重複がWidgetない 1 つだけになります。ArrayList<Widget>Widget

より良い方法があるかもしれませんが、2 つの s が重複しているかどうかを判断するために使用できるWidgetオーバーライドされたequalsメソッドがあると仮定します。Widget

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

これを達成するための最もアルゴリズム的に効率的な方法を探しています。Apache Commons やその他のオープン ソース ライブラリも喜んで使用します。前もって感謝します!

4

3 に答える 3

12

ごとArrayList<Widget>に、 を使用して各要素をSet<Widget>(HashSetまたはTreeSet、何らかの方法で順序付けできるか、またはハッシュ可能であるかに応じて) に追加し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;
    }
}

a を使用したいが、クラスに実装しTreeSetたくない場合は、セット自体にオブジェクトを与えることができます。Comparable<T>WidgetComparator

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());
            }
           });
于 2013-05-09T02:17:10.053 に答える
9

私はこのようにします

Set<Widget> set = new HashSet<>(list1);
set.addAll(list2);
List<Widget> mergeList = new ArrayList<>(set);
于 2013-05-09T02:20:55.333 に答える
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 からすべての重複値を削除します。

于 2013-05-09T02:19:52.637 に答える