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?
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
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:
equals()
renvoie vraiLa réponse est "oui": wordSet.contains(b)
renverra toujours true
Deux choses:
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.
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.
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.
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;
}
Égalité. Dans votre exemple, contains()
renvoie true, car le HashSet vérifie a.equals( b )
.