2010-02-08 6 views
1

J'ai un code pour renvoyer une arrayList avec les doublons d'un ArrayList mais semble cela ne fonctionne pas, je compare tous les éléments du tableau ...à Doublons Arraylist, comparant divers champs java

public ArrayList<ObjectList> duplicates(ArrayList<ObjectList> someObjectsList) { 

    ArrayList<ObjectList> ret = new ArrayList<ObjectList>(); 
    for (ObjectList aSomeObjectsList: someObjectsList) { 

     String field1 = aSomeObjectsList.get1(); 
     String field2 = aSomeObjectsList.get2(); 
     String field3 = aSomeObjectsList.get3(); 
     String field4 = aSomeObjectsList.get4(); 
     for (ObjectList someObject : ret) { 
      if (
       field1.trim().equals(someObject.get1())&& 
       field2.trim().equals(someObject.get2())&& 
       field3.trim().equals(someObject.get3())&& 
       field4.trim().equals(someObject.get4())  
       ){ 
       ret.add(aSomeObjectsList); 

      } 
     } 

    } 
    return ret; 
} 

mais je suppose que je suis en train de faire quelque chose de mal parce qu'il ne retourne rien, et je sais qu'il a duplictates sous ce 4 critères sur le terrain

Merci à l'avance

Répondre

1

Voici comment vous pouvez faire cela. J'ai défini une classe de base ObjectList qui montre un moyen de mettre en œuvre equals et hashCode. Notez que cela suppose que toutes les variables internes sont non nulles. Si ces variables peuvent contenir null alors vous devrez vérifier cela lors du calcul de equals/hashCode. De plus, les objets de cette classe doivent également implémenter eux-mêmes equals/hashCode.

public class ObjectList { 

    private int h; 

    private Object obj1; 
    private Object obj2; 
    private Object obj3; 
    private Object obj4; 

    @Override 
    public boolean equals(final Object o) { 
     if (!(o instanceof ObjectList)) 
      return false; 

     final ObjectList that = (ObjectList) o; 
     return that.obj1.equals(obj1) && that.obj2.equals(obj2) 
      && that.obj3.equals(obj3) && that.obj4.equals(obj4); 
    } 

    @Override 
    public int hashCode() { 
     // caches the hashcode since it could be costly to recompute every time 
     // but this assumes that your object is essentially immutable 
     // (which it should be if you are using equals/hashCode. If this is not 
     // true and you want to just temporarily use this when doing the duplicate 
     // test, move the h variable definition from the object level to this method 
     // and remove this if statement. 
     if (h != 0) 
      return h; 

     h = obj1.hashCode(); 
     h = h * 31 + obj2.hashCode(); 
     h = h * 31 + obj3.hashCode(); 
     h = h * 31 + obj4.hashCode(); 
     return h; 
    } 

} 

public Collection<ObjectList> duplicates(
     final Collection<ObjectList> someObjectsList) { 

    final Set<ObjectList> unique = new HashSet<ObjectList>(someObjectsList); 
    final ArrayList<ObjectList> ret = new ArrayList<ObjectList>(someObjectsList); 
    for (final ObjectList o : unique) { 
     ret.remove(o); 
    } 

    // The ret list now contains the duplicate instances; instances 
    // with more than two occurrences will occur multiple times still in 
    // this list. 
    return ret; 

    // If you want a list of unique duplicate instances then, comment out the above 
    // return and uncomment this one. 
    // return new HashSet<ObjectList>(ret); 
} 

En utilisant Collection<ObjectList> est mieux, si vous pouvez le faire, tant pour le paramètre et la valeur retournée de sorte que vous pouvez varier les implémentations (ArrayList, Set, etc).

+0

Merci, je fais cette implémentation et semble fonctionner correctement, Aussi je sais que je manque beaucoup de syntaxe du langage et beaucoup de ses fonctionnalités, merci Kevin – cMinor

3
for (Object someObject : ret) { 
     if (
      field1.trim().equals(someObject.get1())&& 
      field2.trim().equals(someObject.get2())&& 
      field3.trim().equals(someObject.get3())&& 
      field4.trim().equals(someObject.get4())  
      ){ 
      ret.add(aSomeObjectsList); 

     } 
    } 

La boucle ci-dessus ne fonctionnerait pas, car elle a la taille de zéro.

Ici, vous allez,

public Set<ObjectList> duplicates(ArrayList<ObjectList> someObjectsList) { 

    Set<ObjectList> originals = new HashSet<ObjectList>(); 
    Set<ObjectList> duplicates = new HashSet<ObjectList>(); 

    for (ObjectList aSomeObjectsList: someObjectsList) { 
     boolean added = originals.add(aSomeObjectsList); 
     if(!added){ 
      duplicates.add(aSomeObjectsList); 
     }  
    } 
    return duplicates; 
} 

Cela fonctionnerait, à condition que votre ObjectList classe ont la mise en œuvre correcte de hashCode() et equals() méthodes.

Avertissement: Cette implémentation ne fournira pas les informations sur le nombre de fois qu'un objet particulier a été dupliqué dans la liste fournie. Il vous dira simplement qu'un objet particulier a été dupliqué. J'ai supposé que c'était votre véritable intention. Si vous voulez compter, combien de fois, vous devez modifier le code en conséquence.

Indice/Suggestion: Vous devez remplacer la méthode equals() et y placer une fois pour toutes votre vérification d'égalité des champs.

+0

Comment puis-je fournir la classe ObjectList hashcode() et equals() Je ne l'obtiens toujours pas. Dois-je créer une interface? publicList ObjectList implémente le comparateur {} etc ... ????? MERCI – cMinor

+0

Non, remplacez simplement la méthode 'equals()' et 'hashcode()'. Pas besoin de «étendre» ou de «mettre en œuvre» quoi que ce soit. Regardez l'exemple ici, http://www.javapractices.com/topic/TopicAction.do?Id=28. Et s'il vous plaît essayez d'apprendre et de comprendre la langue et ses caractéristiques. Prenez un bon livre ou un tutoriel. –

2

Cela ne devrait pas compiler - si aSomeObjectsList est un Object alors il ne dispose pas de méthodes get1(), get2(), etc.

Votre logique ne fonctionnera pas parce que vous n'êtes pas vérifier chaque élément dans votre entrée List contre les autres éléments de l'entrée List; Au lieu de cela, vous essayez de vérifier le retour List.

En outre, ce n'est pas un moyen très efficace de vérifier les doublons dans une collection. Une meilleure façon serait d'utiliser un HashMap, où vous pouvez vérifier l'appartenance à un ensemble à peu près à temps constant. Si vous devez utiliser un List, triez-le d'abord (en supposant que vos objets ont un ordre naturel) et vérifiez l'égalité des membres adjacents.

À l'exception de ces deux, il suffit d'utiliser List.contains().

+0

Vrai aussi :). Je n'ai pas remarqué. –