HashMapのキーが文字配列の場合:
HashMap<String[], String> pathMap;
新しく作成された文字列配列を使用してマップにアクセスできますか、それとも同じString []オブジェクトである必要がありますか?
pathMap = new HashMap<>(new String[] { "korey", "docs" }, "/home/korey/docs");
String path = pathMap.get(new String[] { "korey", "docs" });
同じオブジェクトである必要があります。 HashMap
はequals()
を使用してキーを比較し、Java)の2つの配列は、それらが同じオブジェクトである場合にのみ等しくなります。
値の等価性が必要な場合は、_String[]
_をラップし、equals()
およびhashCode()
に適切なセマンティクスを提供する独自のコンテナークラスを作成します。この場合、オブジェクトのハッシュコードを変更すると、ハッシュベースのコンテナクラスが大混乱に陥るので、コンテナを不変にすることが最適です。
編集
他の人が指摘したように、_List<String>
_にはコンテナオブジェクトに必要なセマンティクスがあります。したがって、次のようなことができます。
_HashMap<List<String>, String> pathMap;
pathMap.put(
// unmodifiable so key cannot change hash code
Collections.unmodifiableList(Arrays.asList("korey", "docs")),
"/home/korey/docs"
);
// later:
String dir = pathMap.get(Arrays.asList("korey", "docs"));
_
いいえ。ただし、List<String>
を使用できます。これは期待どおりに機能します。
Java Object
のhashCode()
を使用し、それをオーバーライドしないでください(equals()
およびtoString()
と同じこと)]の配列。だから、あなたは できない 配列をハッシュマップキーとして使用しないでください。
テッド・ホップは正しい、それは同じオブジェクトでなければならない
詳細については、この例を参照してください
public static void main(String[] args) {
HashMap<String[], String> pathMap;
pathMap = new HashMap<String[], String>();
String[] data = new String[] { "korey", "docs" };
pathMap.put(data, "/home/korey/docs");
String path = pathMap.get(data);
System.out.println(path);
}
}
上記を実行すると、「ドキュメント」が印刷されます。
単純なJava Array
をHashMap
のキーとして使用することはできません。(できますが、期待どおりに機能しません。)
ただし、Arrayへの参照を持ち、hashCode()
およびequals()
もオーバーライドするラッパークラスを作成できます。
ほとんどの場合、配列内の文字列が病理学的ではなく、コンマの後にスペースが含まれていない場合、Arrays.toString()
を一意のキーとして使用できます。つまり、Map
は_Map<String, T>
_になります。そして、配列_myKeys[]
_のget/putは
_T t = myMap.get(Arrays.toString(myKeys));
myMap.put(Arrays.toString(myKeys), myT);
_
必要に応じて、いくつかのラッパーコードを挿入できます。
素晴らしい副作用は、キーが不変になったことです。もちろん、配列myKeysを変更してからget()
を試しても、見つかりません。
文字列のハッシュは高度に最適化されています。したがって、私のguessは、このソリューションは、少し遅くて気味が悪いとはいえ、不変リストを使用する@Ted Hoppソリューションよりも高速で、メモリ効率がよい(オブジェクトの割り当てが少ない)ことです。 Arrays.toString()
がキーに対して一意であるかどうかを考えてください。そうでない場合、または疑問がある場合(たとえば、String []はユーザー入力に由来する)、Listを使用します。