web-dev-qa-db-fra.com

Une méthode Java HashSet <String> contient-elle () testerait-elle l'égalité des chaînes ou l'identité de l'objet?

Disons que j'ai ce code en Java:

HashSet<String> wordSet = new HashSet<String>();
String a = "hello";
String b = "hello";
wordSet.add(a);

Est-ce que wordSet.contains(b); retournerait true ou false? D'après ce que je comprends, a et b font référence à des objets différents même si leurs valeurs sont les mêmes. Donc contains() devrait retourner false. Cependant, lorsque j'exécute ce code, il renvoie true. Renvoie-t-il toujours true peu importe d'où vient l'objet String b tant que b contient la valeur "hello"? Suis-je assuré toujours? Sinon, quand ne suis-je pas assuré? Et si je voulais faire quelque chose de similaire avec des objets autres que des cordes?

46
OkonX

Il utilise equals() pour comparer les données. Ci-dessous est du javadoc pour Set

ajoute l'élément spécifié e à cet ensemble si l'ensemble ne contient aucun élément e2 tel que (e == null? e2 == null: e.equals (e2)).

La méthode equals() pour String effectue une comparaison caractère par caractère. Depuis le javadoc pour String

Le résultat est vrai si et seulement si l'argument n'est pas nul et est un objet String qui représente la même séquence de caractères que cet objet

52
Aravind R. Yarram

En fait, HashSet fait ni l'un ni l'autre.

Son implémentation utilise un HashMap, et voici le code pertinent qui détermine si l'ensemble contains() (en fait c'est à l'intérieur de la méthode getEntry () de HashMap):

if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))

lequel:

  • nécessite que les hachages soient égaux, et
  • requiert soit l'égalité d'objet ou equals() renvoie vrai

La réponse est "oui": wordSet.contains(b) renverra toujours true

6
Bohemian

Deux choses:

  1. Un ensemble serait plutôt inutile s'il n'appelait pas la méthode equals () pour déterminer l'égalité. wordset.contains (b) renverra true car a.equals (b) == true.

  2. Vous ne pouvez pas être totalement sûr que a et b pointent vers des objets différents. Consultez String.intern () pour plus de détails.

3
Chip

En fait, a et b font référence au même objet, car les littéraux de chaîne dans Java sont automatiquement internés.

3
Perception

En fin de compte, contains recherchera la méthode equals plutôt que sa validation d'ID d'objet pour la méthode contains. Par conséquent, la méthode equals sera appelée pour l'appel contains. Il s'agit de la structure d'appel de la méthode contains.

private transient HashMap<E,Object> map;
    public boolean contains(Object o) {
    return map.containsKey(o);
    }


    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }


    final Entry<K,V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }
1
Bhavik Ambani

Égalité. Dans votre exemple, contains() renvoie true, car le HashSet vérifie a.equals( b ).

0
Dawood ibn Kareem