IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

[HashSet] C'est possible de mettre des doublons ! :-(


Sujet :

Collection et Stream Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut [HashSet] C'est possible de mettre des doublons ! :-(
    Bonjour,
    En résolvant un bug ce matin, je viens de me rendre compte à mes dépends qu'on peut avoir des doublons dans une hashSet même si vos methodes hashCode et equals sont bien implémentées. Il suffit de modifier un des éléments après les avoir ajoutés dans la hashSet. Exécutez le code suivant et voyez:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    import java.util.HashSet;
    import java.util.Set;
     
    public class HashsetTest {
       public static void main(String[] args) {
          Set<Person> personSet = new HashSet<Person>();
          personSet.add(new Person("Jeremie"));
          personSet.add(new Person("Gérard"));
          personSet.add(new Person("Tommy"));
          personSet.add(new Person("Jacques"));
     
          for ( Person p : personSet ) {
             if ( p.name.equals("Gérard") || p.getName().equals("Jacques") ) {
                p.name = "Tommy";
             }
          }
          System.out.println("Number of items in the Set : " + personSet.size());
          for ( Person p : personSet ) {
             System.out.println(p);
          }
     
          System.out.println("Number of items in the Set : " + personSet.size());
          System.out.println();
          System.out.println("Equality tests ");
          System.out.println();
          Person[] pList = personSet.toArray(new Person[] {});
          for ( int i = 0; i < pList.length - 1; i++ ) {
             if ( pList[i].equals(pList[i + 1]) ) {
                System.out.println(pList[i] + " and " + pList[i + 1] + " are equals ");
             }
             else {
                System.out.println(pList[i] + " and " + pList[i + 1] + " are not equals ");
             }
          }
       }
     
       static class Person {
          private String name;
     
          Person(String name) {
             this.name = name;
          }
     
          public String toString() {
             return (name == null ? "" : name);
          }
     
          @Override
          public boolean equals(Object o) {
             if ( o == this )
                return true;
             if ( !(o instanceof Person) ) {
                return false;
             }
             return this.name.equals(((Person)o).name);
          }
     
          @Override
          public int hashCode() {
             final int seed = 31;
             return seed + ((name == null) ? 0 : name.hashCode());
          }
     
          public String getName() {
             return name;
          }
     
          public void setName(String name) {
             this.name = name;
          }
       }
    }

  2. #2
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Bien sûr, tu modifies les noms qui servent de hash APRÈS l'ajout.

    En théorie, il faudrait que tes données servant de hash/equals soient immutables pour les utiliser dans un HashXXX...

    D'ailleurs, dans la javadoc de Object:
    Citation Envoyé par Javadoc
    public int hashCode()

    Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

    The general contract of hashCode is:

    * Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
    * If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
    * It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/04/2013, 14h11
  2. Est il possible de mettre des images a la place des bordures
    Par saperlipopeye dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 26/11/2009, 20h49
  3. Réponses: 1
    Dernier message: 03/04/2009, 18h23
  4. Réponses: 9
    Dernier message: 26/05/2008, 15h38
  5. Réponses: 1
    Dernier message: 11/09/2007, 16h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo