2013-05-09 11 views
9

Ich habe eine Situation, in der ich 2+ erhalten werde und ich muss in der Lage sein, alle Listen zusammenzuführen und alle doppelten Widget zu entfernen, so dass ich nur mit 1 ArrayList<Widget>, die alle Widget s aus allen zusammengeführten Listen enthält, aber ohne Duplikate.Die beste Möglichkeit zum Zusammenführen und Entfernen von Duplikaten aus mehreren Listen in Java

Widget Angenommen hat eine außer Kraft gesetzt equals Methode, die kann zur Bestimmung, ob zwei Widget s verwendet werden, sind Duplikate, obwohl es eine bessere Art und Weise sein kann:

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

der Suche nach den meisten algorithmisch effizient zu bewerkstelligen, Dies. Ich bin glücklich, Apache Commons oder andere Open-Source-Bibliotheken zu verwenden, die mir auch helfen würden! Danke im Voraus!

Antwort

11

Für jedes ArrayList<Widget>, fügen jedes Element auf einem Set<Widget> (HashSetTreeSet oder, je nachdem, ob sie in irgendeiner Weise zu bestellen, oder hashable sind) unter Verwendung von addAll. Sets enthalten standardmäßig keine Duplikate.

Sie können diese Set wieder in eine (Array)List konvertieren, wenn Sie am Ende benötigen.

Hinweis müssen Sie hashCode für Ihre Widget Klasse implementieren, wenn Sie einen HashSet verwenden entscheiden, aber wenn Sie equals, ein außer Kraft gesetzt haben, sollten Sie dies doch tun.

Edit: Hier ist ein Beispiel:

//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; 
    } 
} 

Wenn Sie eine TreeSet verwenden möchten, aber nicht wollen, Comparable<T> auf Ihrer Widget Klasse implementieren, können Sie das Gerät selbst ein Comparator Objekt geben:

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

Wow dank @Yuushi (+1) - werde ich eine Laufzeitausnahme, wenn ich versuche, eine Betrogene zu dem Satz hinzufügen? Oder ignoriert Java einfach den hinzugefügten Dupe (was ich will). Danke noch einmal! – IAmYourFaja

+0

Java ignoriert einfach das hinzugefügte Duplikat –

+1

@IamYourFaja Es ignoriert einfach den Betrogenen. – Yuushi

2

Verwenden Set Sammlung Klasse,

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; 

Jetzt wird Set alle Duplikate von Ihrer ArrayList entfernen.

+0

Danke @buptcoder (+1) - bitte sehen Sie meine letzte Frage an Yuushi in seiner/ihrer Antwort abov e - Ich habe dieselbe Frage an dich! – IAmYourFaja

8

Ich würde es tun, um diese Art und Weise

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

Danke @Evgeniy (+1) - bitte sehen Sie meine letzte Frage an Yuushi in seiner Antwort oben - ich habe die gleiche Frage für Sie! – IAmYourFaja

+0

Da wir Set-Duplikate verwenden, wird nicht hinzugefügt. Es wird keine Ausnahmen geben –

Verwandte Themen