6

オブジェクトをキーとして使用してコードが安全であることを確認したいだけです。Integer以下に短い例を示します。

Integer int1 = new Integer(1337);
Integer int2 = new Integer(1337);

if (int1 == int2) {
    System.out.println("true");
} else {
    System.out.println("false");
}

if (int1.equals(int2)) {
    System.out.println("true");
} else {
    System.out.println("false");
}

Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(int1, null);
map.put(int2, null);

System.out.println(map.size());

コードが出力されます

false
true
1

それは私が期待していたことです。参照は異なりますが、互いに等しいです。今、私はマップの動作に興味があります。

  • Map や Set などのコレクションが、参照ではなくコンテンツによってキーを比較することが保証されていますか?
  • または、実際の実装に依存しHashMapますか?
4

8 に答える 8

7

メソッドequalsが呼び出されるため、比較されるのはコンテンツです。

上記の2つの質問について:

2 つのオブジェクトo1and o2(簡単にするために、 and と仮定しo1!=nullますo2!=null) が与えられた場合、hasp マップは、最終的に、それらが同じ値を持っているかどうかを判断する必要があります。(最終的には、と が同じハッシュ値を持っているHaspMapかどうかもチェックしますが、これは質問のコンテキストでは重要ではありません)。メソッドを呼び出すことでこれを行います。が false である限り、2 つのオブジェクトは によって 2 つの異なるキーと見なされます。o1o2equals()o1.equals(o2)HashMap

HashSetequals()また、要素がすでにセットに含まれているかどうかを判断するために呼び出します。 http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add%28E%29を参照してください。

TreeMap一方、 は 2 つのオブジェクトを比較し、それらが等しいかどうか、またはどちらが大きいかを判断する必要があります。を呼び出すことでこれを行いcompareTo()ます。したがって、重要なのはその戻り値です(または、コンストラクタhttp://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html#TreeMapo1.compareTo(o2)でツリー マップを作成した場合)。%28java.util.Comparator%29、コンパレータが使用されます)。

したがって、保証されているのは、HashMapHashSetでは メソッドequals()を使用してオブジェクトを区別し、 ではTreeMapメソッドを使用することですcompareTo()

于 2012-12-19T12:35:36.140 に答える
6

Q1: - Map や Set などのコレクションが、参照ではなく内容によってキーを比較することが保証されていますか?

A1: - いいえ。Collection、Map、および Set はインターフェイスです。彼らが保証しているのは、可能なメソッドの契約だけです。

Q2: - HashMap のように、実際の実装に依存しますか?

A2: はい。クラスが比較をどのように処理するかは、開発者の決定です。

HashMap は 2 つのものを使用してオブジェクトを割り当てます

まず - はObject#hashCode()、インデックスの計算に使用されます。

2つ目はObject#equals()、それが使用され、ハッシュコリジョンが発生する場所です。

于 2012-12-19T12:50:12.277 に答える
3

の実装を開くと、どこでもメソッドjava.util.AbstractMapを使用してキーと値の式がチェックされていることがわかります。Object#equalsマップ内で実際に比較されるものは、メソッドのキー/値の実装によって異なりますObject#equals

于 2012-12-19T12:36:41.537 に答える
1

ここで Integer は Waraper の最終クラスであり、オーバーライドされequals()たメソッドであるため、コンテンツのみを比較します。

したがって、使用する整数が任意のラッパー クラスである場合、問題はありません。Map

カスタムクラスをキーとして使用したい場合はequals() and hashcode()、重複を避けるためにメソッドをオーバーライドする必要がありますMap

于 2012-12-19T12:37:02.007 に答える
0

項目を HashMap (および拡張により HashSet) 内に配置する場合、hashCode を使用して (単純な線形関数によって変換されます)、項目を内部コレクション内のどこに配置する必要があるかを決定します。

次に、決定された場所で、(o1 == o2 || o1.equals(o2)) を使用して (そこに保存されているすべてのアイテムの中から) 同一のオブジェクトを検索し、参照が異なる場合は #equals 関数が呼び出されます。シンプルな #equals 呼び出し。同一のアイテムが見つかった場合、その割り当てられた値は新しいものに置き換えられます。そうでない場合、新しいアイテムは単に内部コレクションに追加されます。

于 2014-04-23T07:32:49.187 に答える
0

ハッシュマップの場合、キーは equals() および hashcode() メソッドを使用して比較されます。

上記の例では、hashcode() と equals() の両方が Integer クラスでオーバーライドされています。HashMap が 2 つのキーを比較する場合、まずそのオブジェクトの hashcode() を取得し、次にこのオブジェクトと同じ hashcode 値を持つキーに対して equals メソッドを呼び出します。

于 2012-12-19T12:41:16.847 に答える
0

実際には、に指定した /keyのequals()実装に依存します。KMap

a で同じことを試してみて、Map<Object,String>何が起こるか見てみましょう (ヒント:Objectが等しいためには、実際には同じオブジェクトでなければなりません)。

乾杯

于 2012-12-19T12:36:46.513 に答える
0

1 つ目は、2 つの異なるオブジェクト (参照) を比較します --> false。

2 番目は、これらのオブジェクトの値を比較 (等しい) --> true

Hashmap は、オブジェクトの equals および hascode メソッドを使用して一意のキーを決定します。そのため、同じキーが 2 回挿入され、残りの要素が 1 つになります。2番目のもの。Map#put javadoc を見て、何が起こっているかを確認してください。

于 2012-12-19T12:37:06.360 に答える