2013-05-09 16 views
9

2+ ArrayList<Widget>'u alacağım bir durumum var ve tüm listeleri birleştirip Widget yinelenmesini kaldırmam gerekiyor. Birleştirilmiş tüm listelere ait tüm Widget s değerlerini içeren, ancak herhangi bir kopya içermeyen 1 ArrayList<Widget>.Java'da birden çok listeden çoğaltmaları birleştirmenin ve çıkarmanın en iyi yolu

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

gerçekleştirerek en algoritmik verimli şekilde Aranan:

Widget varsayalım daha iyi bir yolu olabilir, ancak , çiftleri olup iki Widget s belirlemek için kullanılabilecek bir geçersiz equals yöntemi vardır bu. Apache Commons'ı veya bana yardımcı olacak diğer açık kaynak kodlarını kullanmaktan mutluluk duyuyorum! Şimdiden teşekkürler! Her ArrayList<Widget> için

cevap

11

, addAll kullanılarak (bazı şekilde sipariş edilebilir bağlı olarak, HashSet veya TreeSet veya hashable olan) Set<Widget> a her öğe ekleyin. Setleri varsayılan olarak kopya içermez.

Sonunda ihtiyacınız varsa, bu Set'u (Array)List'a dönüştürebilirsiniz.

Not size HashSet kullanmaya karar eğer Widget sınıf için hashCode uygulamak gerekir, ancak bir equals, geçersiz varsa yine yapmalısınız.

Düzenleme: İşte bir örnek:

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

Bir TreeSet kullanmak istiyor ancak, ayarladığınız kendisi Comparator nesneyi verebilir senin Widget sınıfına Comparable<T> uygulamak istemiyorsanız:

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

@Yuushi teşekkür vay yapacağını (1) - Ben sete bir dupe eklemeye çalışırsanız bir çalışma zamanı özel alacak? Ya da Java eklenen dupe'yi görmezden gelir (istediğim şey). Tekrar teşekkürler! – IAmYourFaja

+0

Java, eklenen duplicate –

+1

@IAmYourFaja'yı yalnızca görmezden gelir. – Yuushi

2

Kullanım Set Koleksiyon Sınıfı,

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; 

Şimdi burada Set, ArrayList öğenizdeki tüm yinelenen değerleri kaldıracaktır.

+0

Teşekkürler @buptcoder (+1) - benim cevabında Yuushi için son soruma bakın abov e - Senin için aynı sorum var! – IAmYourFaja

8

ben bu şekilde

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

Teşekkürler @Evgeniy (+1) - Lütfen yukarıdaki cevabı Yuushi'ye verdiğim son soruma bakın - Ben de sizin için aynı sorum var! – IAmYourFaja

+0

Set'i kullandığımız için çoğaltma eklenmeyecek. İstisnalar olmayacak –

İlgili konular