同じキーをHashMap
のput
メソッドに複数回渡すと、元の値はどうなりますか?そして、その値が繰り返されたとしてもどうでしょうか。これに関する文書は見つかりませんでした。
ケース1:キーの上書き値
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));
surely not one
を受け取ります。
ケース2:重複値
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));
one
を得ます。
しかし、他の値はどうなりますか?私は学生に基本を教えていました、そして私はこれを頼まれました。 Map
は、最後の値が参照されるバケットのようなものです(ただし、メモリ内にありますか)。
定義上、put
コマンドは、マップ内の指定されたキーに関連付けられている以前の値を置き換えます(概念的には、プリミティブ型の配列インデックス操作のようなものです)。
マップは単にその値への参照を削除します。そのオブジェクトへの参照が他に何も保持されていない場合、そのオブジェクトはガベージコレクションの対象になります。さらに、Javaは指定されたキーに関連付けられた以前の値(存在しない場合はnull
)を返すため、存在したものを特定し、必要に応じて参照を維持できます。
ここでより多くの情報: HashMap Doc
答えは Map#put(K、V) のJavadocにあります(実際には何かを返します)。
public V put(K key, V value)
指定された値をこのマップ内の指定されたキーに関連付けます(オプションの操作)。マップが以前にこのキーのマッピングを含んでいた場合は、古い値が指定された値に置き換えられます。 (マップ
m
は、m.containsKey(k)
がk
を返す場合に限り、キーtrue
へのマッピングを含むと言われます。)パラメータ:
key
- 指定された値が関連付けられるキー。value
- 指定されたキーに関連付けられる値.戻り値:
指定されたキーに関連付けられた以前の値、またはnull
のマッピングがなかった場合はkey
。 (実装がnull
値をサポートする場合、null
の戻り値は、マップが以前にkey
を指定されたnull
に関連付けたことを示すこともできます。)
そのため、mymap.put("1", "a string")
を呼び出すときに戻り値を代入しないと、単に参照されなくなり、ガベージコレクションの対象になります。
キーの以前の値はドロップされ、新しい値に置き換えられます。
キーに与えられたすべての値を保持したい場合は、次のように実装することを検討してください。
import org.Apache.commons.collections.MultiHashMap;
import Java.util.Set;
import Java.util.Map;
import Java.util.Iterator;
import Java.util.List;
public class MultiMapExample {
public static void main(String[] args) {
MultiHashMap mp=new MultiHashMap();
mp.put("a", 10);
mp.put("a", 11);
mp.put("a", 12);
mp.put("b", 13);
mp.put("c", 14);
mp.put("e", 15);
List list = null;
Set set = mp.entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
list=(List)mp.get(me.getKey());
for(int j=0;j<list.size();j++)
{
System.out.println(me.getKey()+": value :"+list.get(j));
}
}
}
}
これはキー/値機能であり、実際の値を取得したいときに入力されたキーに属する値があるため、複数の値に対して重複キーを持つことはできません。
あなたの例であなたが "1"の値を取得したいときはどれですか?
これがすべての値に固有のキーを持つ理由ですが、Java標準のlibによるトリックを持つことができます。
import Java.util.ArrayList;
import Java.util.HashMap;
import Java.util.Map;
public class DuplicateMap<K, V> {
private Map<K, ArrayList<V>> m = new HashMap<>();
public void put(K k, V v) {
if (m.containsKey(k)) {
m.get(k).add(v);
} else {
ArrayList<V> arr = new ArrayList<>();
arr.add(v);
m.put(k, arr);
}
}
public ArrayList<V> get(K k) {
return m.get(k);
}
public V get(K k, int index) {
return m.get(k).size()-1 < index ? null : m.get(k).get(index);
}
}
そして、あなたはこのようにそれを使うことができます:
public static void main(String[] args) {
DuplicateMap<String,String> dm=new DuplicateMap<>();
dm.put("1", "one");
dm.put("1", "not one");
dm.put("1", "surely not one");
System.out.println(dm.get("1"));
System.out.println(dm.get("1",1));
System.out.println(dm.get("1", 5));
}
と印刷の結果は次のとおりです。
[one, not one, surely not one]
not one
null
このマップ内の指定されたキーに指定された値を関連付けます。マップが以前にキーのマッピングを含んでいた場合、古い値が置き換えられます
地図がバケツのようなものであるかどうかについてのあなたの質問に:いいえ。
これはname=value
の組を含むリストのようなものですが、name
はStringである必要はありません(ただし可能です)。
要素を取得するには、get() - メソッドにキーを渡します。これにより、割り当てられたオブジェクトが返されます。
また、ハッシュマップは、getメソッドを使ってオブジェクトを取得しようとしている場合、実際のオブジェクトと指定したオブジェクトを比較しないことを意味します。リストを反復処理し、現在の要素に指定したキーをcompare()する必要があります。
これは非効率的です。代わりに、あなたのオブジェクトが何から構成されていようとも、それは両方のオブジェクトからいわゆるハッシュコードを計算し、それらを比較します。 2つの(場合によっては非常に複雑な)オブジェクト全体ではなく、2つのint
を比較する方が簡単です。ハッシュコードは、事前定義された長さ(int)を持つ要約のように想像できます。したがって、ハッシュコードは一意ではなく、衝突があります。ハッシュコードの規則は、私がリンクを挿入した文書にあります。
これについてもっと知りたい場合は、 javapractices.com と technofundoの記事を見てみたいと思うかもしれません。 .com
よろしく
それはそれぞれのキーのマップの既存の値を置き換えます。そして同じ名前のキーが存在しない場合は、与えられた値でキーを作成します。例えば:
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","two");
OUTPUTkey = "1"、value = "two"
そのため、以前の値は上書きされます。
私はいつも使っていました:
HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
ひとつの識別キーに複数のことを適用したい場合.
public void MultiHash(){
HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
String key = "Your key";
ArrayList<String> yourarraylist = hashy.get(key);
for(String valuessaved2key : yourarraylist){
System.out.println(valuessaved2key);
}
}
あなたはいつでもこのようなことをして自分自身を迷路にすることができます!
public void LOOK_AT_ALL_THESE_HASHMAPS(){
HashMap<String, HashMap<String, HashMap<String, HashMap<String, String>>>> theultimatehashmap = new HashMap <String, HashMap<String, HashMap<String, HashMap<String, String>>>>();
String ballsdeep_into_the_hashmap = theultimatehashmap.get("firststring").get("secondstring").get("thirdstring").get("forthstring");
}
はい、これは値を持つすべての1つのキーが最後に追加された値で上書きされることを意味します。
たとえあなたがループで表示しようとしていても、それはまた同じキーを持つ一つのキーと値のみを表示します。
ところで、このキーが存在しない場合にのみ置くといったセマンティクスが必要な場合は。あなたはputIfAbsent()
関数と一緒にconcurrentHashMap
を使うことができます。これをチェックしてください。
https://docs.Oracle.com/javase/7/docs/api/Java/util/concurrent/ConcurrentHashMap.html#put(K、%20V)
concurrentHashMap
は "ロックストライピング "スループットを向上させるメカニズム。
JDKからのマップは重複したキーの下にデータを格納するためのものではありません。
せいぜい新しい値が前の値を上書きします。
悪いシナリオは例外です(例:ストリームとして集めようとしたとき):
重複なし
Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))
OK。あなたは得るでしょう:$ 2 ==> {one = one}
複製ストリーム
Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))
例外Java.lang.IllegalStateException:重複キー1(1ではなく1の値のマージを試みました) Collectors.duplicateKeyExceptionで(Collectors.Java:133) Collectors.lambda $ uniqKeysMapAccumulator $ 1で(Collectors.Java:180)|でReduceOps $ 3ReducingSink.accept(ReduceOps.Java:169)|お問い合わせSpliteratorsで$ ArraySpliterator.forEachRemaining(Spliterators.Java:948)| AbstractPipeline.copyIntoで(AbstractPipeline.Java:484)| AbstractPipeline.wrapAndCopyInto(AbstractPipeline.Java:474)でReduceOps $ ReduceOp.evaluateSequential(ReduceOps.Java:913)| AbstractPipeline.evaluateで(AbstractPipeline.Java:234)| ReferencePipeline.collectで(ReferencePipeline.Java:578)|で(#4:1)
重複したキーを処理するには - 他のパッケージを使用してください。例: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
重複したキーを扱う実装は他にもたくさんあります。それらはウェブに必要です(例:重複したクッキーキー、HTTPヘッダは同じフィールドを持つことができます、など)。
がんばろう! :)