web-dev-qa-db-ja.com

Java HashSet <String> 's contains()メソッドは、文字列またはオブジェクトIDの同等性をテストしますか?

私はこのコードをJavaで持っているとしましょう:

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

wordSet.contains(b);trueまたはfalseを返しますか?私が理解したことから、abは、それらの値が同じであっても異なるオブジェクトを参照します。したがって、contains()falseを返す必要があります。ただし、このコードを実行すると、trueが返されます。 trueが値_"hello"_を含む限り、Stringオブジェクトbがどこから来ても、常にbを返しますか?これは保証されますか?常に?そうでない場合、いつこれが保証されないのですか?そして、文字列以外のオブジェクトで同様のことをしたい場合はどうなりますか?

46
OkonX

equals()を使用してデータを比較します。以下は Setのjavadoc

セットに要素e2が含まれない場合(e == null?e2 == null:e.equals(e2))に、指定された要素eをこのセットに追加します。

Stringのequals()メソッドは、文字ごとの比較を行います。 Stringのjavadoc から

引数がnullではなく、このオブジェクトと同じ文字シーケンスを表すStringオブジェクトである場合にのみ、結果はtrueです

52

実際、HashSetはneitherを実行します。

その実装はHashMapを使用します。セットcontains()(実際にはHashMapのgetEntry()メソッド内にあるかどうか)を決定する関連コードは次のとおりです。

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

どれ:

  • ハッシュが等しいことを必要とし、
  • eitherオブジェクトの等価性またはequals()がtrueを返します

答えは「はい」です。wordSet.contains(b)は常にtrueを返します

6
Bohemian

2つのこと:

  1. 等しいかどうかを判断するためにequals()メソッドを呼び出さない限り、セットはほとんど役に立ちません。 wordset.contains(b)は、a.equals(b)== trueであるため、trueを返します。

  2. Aとbが異なるオブジェクトを指していることを完全に確信することはできません。詳細については、String.intern()を確認してください。

3
Chip

実際、Javaの文字列リテラルは自動的にインターンされるため、aとbは同じオブジェクトを参照します。

3
Perception

最終的に、containsは、containsメソッドのオブジェクトID検証ではなく、equalsメソッドをチェックします。したがって、equalsメソッドはcontains呼び出しに対して呼び出されます。これは、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

平等。あなたの例では、HashSetはcontains()をチェックするため、a.equals( b )はtrueを返します。

0