149

以下のコードを検討してください。

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size()HashSet重複を許可しないため1を与えるため、1つの要素のみが格納されます。

重複する要素を追加するのか、それとも前の要素を置き換えるのか、それとも単に追加しないのかを知りたいのですが。

HashMapまた、同じ場合に使用するとどうなりますか?

4

8 に答える 8

265

の場合HashMap、古い値を新しい値に置き換えます。

の場合HashSet、アイテムは挿入されません。

于 2012-10-17T18:14:55.927 に答える
54

最初に知っておく必要があるのは、HashSetのように機能Setすることです。つまり、オブジェクトをに直接追加し、HashSet重複を含めることはできません。に直接値を追加するだけですHashSet

ただし、HashMapタイプMapです。つまり、エントリを追加するたびに、キーと値のペアを追加します。

HashMapで値を複製することはできますが、キーを複製することはできません。新しいエントリではHashMap、古いエントリが置き換えられます。最新のエントリはになりますHashMap

HashMapとHashSet間のリンクを理解する:

キーHashMapを複製することはできません。舞台裏では。HashSetを使用しHashMapます。

オブジェクトをに追加しようとするとHashSet、このエントリは実際にはキーとして-に格納されます。これは、の舞台裏で使用されるものHashMapと同じです。この基礎にはキーと値のペアが必要なため、ダミー値が生成されます。HashMapHashSetHashMap

これで、同じに別の複製オブジェクトを挿入しようとすると、その下にHashSetあるキーとして再び挿入しようとします。HashMapただし、HashMap重複はサポートされていません。したがって、HashSetそのタイプの値は1つだけになります。ちなみに、重複するキーごとに、HashSetのエントリに対して生成される値はランダム/ダミー値であるため、キーはまったく置き換えられません。キーを削除して同じキー(ダミー値は同じ)を追加し直してもまったく意味がないため、無視されます。

概要:

HashMap複製は許可されますがvalues、許可されませんkeysHashSet重複を含めることはできません。

オブジェクトの追加が正常に完了したかどうかを試すために、boolean呼び出し時に返された値をチェックして.add() 、それが返されるtrueかどうかを確認できますfalse。戻っtrueた場合は挿入されました。

于 2012-10-17T18:22:01.100 に答える
23

ドキュメントはこれについてかなり明確です:置き換えHashSet.add ません:

指定された要素がまだ存在しない場合は、このセットに追加します。より正式には、このセットに(e == null?e2 == null:e.equals(e2))のような要素e2が含まれていない場合、指定された要素eをこのセットに追加します。このセットにすでに要素が含まれている場合、呼び出しはセットを変更せずに残し、falseを返します。

しかし、置き換えられますHashMap.put

マップに以前にキーのマッピングが含まれていた場合、古い値が置き換えられます。

于 2012-10-17T18:15:55.977 に答える
4

HashSetの場合、それを置き換えるものではありません。

ドキュメントから:

http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E

"指定された要素がまだ存在しない場合は、このセットに追加します。より正式には、このセットに(e == null?e2 == null:e.equals( e2))。このセットにすでに要素が含まれている場合、呼び出しはセットを変更せずに残し、falseを返します。」

于 2012-10-17T18:18:00.030 に答える
1

私が間違っている場合は訂正してください。ただし、文字列を使用すると、「Hi」==「Hi」が常に真になるとは限りません(必ずしも同じオブジェクトではないため)。

ただし、1の答えが得られる理由は、JVMが可能な場合は文字列オブジェクトを再利用するためです。この場合、JVMは文字列オブジェクトを再利用しているため、Hashmap/Hashsetの項目を上書きします。

ただし、この動作は保証されていません(同じ値「Hi」を持つ別の文字列オブジェクトである可能性があるため)。表示される動作は、JVMの最適化によるものです。

于 2012-10-17T18:19:25.080 に答える
1

HashMap基本的には、を含み、Entryその後に含まれます。内部的には、すでに指摘したように値を置き換えます。しかし、実際にはキーを置き換えますか?いいえ..これがここでのトリックです。その値を基になるキーとして保持し、値は単なるダミーオブジェクトです。したがって、同じ値をHashMap(基になるマップのキー)に再挿入しようとすると、Key(HashSetの値)ではなくダミー値が置き換えられます。Key(Object)Value(Object)HashSetHashMapHashMapHashMapHashMap

HashSetクラスの以下のコードを見てください。

public boolean  [More ...] add(E e) {

   return map.put(e, PRESENT)==null;
}

ここで、eはHashSetの値ですが、基になるmap.andキーのキーは置き換えられません。私が混乱を解消できることを願っています。

于 2017-12-03T16:49:11.320 に答える
0

HashSetはHashMapによってバックアップされるため、最初にHashマップのputメソッドを確認する必要があります。

  1. 重複する値を追加する場合、文字列「One」をHashSetに追加します。
  2. エントリ( "one"、PRESENT)がHashmapに挿入されます(setに追加されたすべての値について、値は "PRESENT"になり、タイプがObjectの場合)
  3. HashmapはエントリをMapに追加し、値を返します。この場合は「PRESENT」であり、エントリが存在しない場合はnullです。
  4. Hashsetのaddメソッドは、Hashmapからの戻り値がnullの場合はtrueを返し、それ以外の場合はfalseを返します。これは、エントリがすでに存在することを意味します。
于 2014-09-09T15:57:42.353 に答える
0

別の言い方をすれば、キーがすでに存在するHashMapにキーと値のペアを挿入すると(ある意味でhashvalue()は同じ値を与え、equal()はtrueですが、2つのオブジェクトはいくつかの点で異なる可能性があります) )、キーは置き換えられませんが、値は上書きされます。キーは、hashvalue()を取得し、それを使用してテーブル内の値を見つけるために使用されます。HashSetはHashMapのキーを使用し、(ユーザーにとって)実際には重要ではない任意の値を設定するため、結果としてセットの要素も置き換えられません。

于 2016-08-24T09:04:24.857 に答える