ハッシュテーブルの同じキーに複数の値を含めることはできますか?そうでない場合、使用できるそのようなクラスまたはインターフェースを提案できますか?
いいえ。それはハッシュテーブルのようなものです。
ただし、Map<YourKeyObject, List<YourValueObject>>
およびリストが存在しない場合にリストを作成するためのいくつかのユーティリティメソッド、または Multimap
from Google Collections のようなものを使用します。
String key = "hello";
Multimap<String, Integer> myMap = HashMultimap.create();
myMap.put(key, 1);
myMap.put(key, 5000);
System.out.println(myMap.get(key)); // prints either "[1, 5000]" or "[5000, 1]"
myMap = ArrayListMultimap.create();
myMap.put(key, 1);
myMap.put(key, 5000);
System.out.println(myMap.get(key)); // always prints "[1, 5000]"
Multimap
は、自家製のソリューションのexact等価ではないことに注意してください。 Hashtable
はすべてのメソッドを同期しますが、Multimap
はそのような保証をしません。つまり、Multimap
を使用すると、複数のスレッドで使用している場合に問題が発生する可能性があります。マップが1つのスレッドでのみ使用されている場合、違いはありません(とにかくHashMap
の代わりに Hashtable
を使用しているはずです)。
ハッシュテーブルの値はObjectなので、リストを保存できます
ハッシュテーブルでは、キーと値のペアを使用して情報を格納します。
Javaでは、 Hashtable
クラスは単一のキーに対して単一の値を受け入れます。以下は、複数の値を単一のキーに関連付ける試みの例です。
Hashtable<String, String> ht = new Hashtable<String, String>();
ht.put("Answer", "42");
ht.put("Hello", "World"); // First value association for "Hello" key.
ht.put("Hello", "Mom"); // Second value association for "Hello" key.
for (Map.Entry<String, String> e : ht.entrySet()) {
System.out.println(e);
}
単一のキー("World"
)に複数の値("Mom"
、"Hello"
)を含めようとすると、Hashtable
のエントリを出力するために次の結果になります。
Answer=42
Hello=Mom
"Hello"
と"World"
のキーと値のペアがHashtable
にありません。2番目の"Hello"
と "Mom
"エントリだけがHashtable
にあります。これは、Hashtable
の単一のキーに複数の値を関連付けることはできないことを示しています。
ここで本当に必要なのは multimap で、これにより複数の値を単一のキーに関連付けることができます。
マルチマップの1つの実装は Multimap
from Google Collections です。
Multimap<String, String> mm = HashMultimap.create();
mm.put("Answer", "42");
mm.put("Hello", "World");
mm.put("Hello", "Mom");
for (Map.Entry<String, String> e : mm.entries()) {
System.out.println(e);
}
これは、Hashtable
を使用した上記の例と似ていますが、動作がまったく異なります。Multimap
を使用すると、単一のキーに複数の値を関連付けることができます。上記のコードを実行した結果は次のとおりです。
Answer=42
Hello=Mom
Hello=World
ご覧のように、"Hello"
キーの場合、それに関連付けられている"Mom"
および"World"
の値。 Hashtable
とは異なり、値の1つを破棄して別の値で置き換えることはありません。 Multimap
は、各キーの複数の値を保持できます。
さらに別のマルチマップの答えを出すのではなく、なぜこれを実行するのかを尋ねます。
複数の値は関連していますか?はいの場合は、それらを保持するデータ構造を作成することをお勧めします。いいえの場合、おそらく別のマップを使用する方が適切です。
キーに基づいて反復できるように、それらをまとめていますか? SkipListのような別の索引付けデータ構造を探したい場合があります。
他の人が指摘したように、いいえ。代わりに、同じキーに多くの値をマップできるMultimap
の使用を検討してください。
の Googleコレクション (update: Guava )ライブラリには1つの実装が含まれており、おそらくあなたの最善の策です。
Edit:もちろん Ericの提案 のようにして、コレクションを値としてHashtable(またはMap、より一般的には)、しかしそれは不必要な定型コードを自分で書くことを意味します。 Googleコレクションのようなライブラリを使用すると、低レベルの「配管」が自動的に行われます。バニラの代わりにマルチマップを使用してコードを簡略化する方法の 良い例 を確認してくださいJavaコレクションクラス。
最初に何をするかを示す答えはありませんでした。
OOの能力で私がこれまでに行った最大のジャンプは、少しでも役立つかもしれないと思われるときに常に別のクラスを作成することにしたときでした-これは私が今までに経験したことの1つですそのパターンに従うことから学んだ。
ほぼ常に、ハッシュテーブルに配置しようとしているオブジェクト間に関係があることがわかりました。たいていの場合、1つまたは2つのメソッドであっても、クラスの余地があります。
実際、HashMap型の構造も必要ないことがよくあります。単純なHashSetで十分です。
主キーとして保存しているアイテムは、新しいオブジェクトのIDになる可能性があります。そのため、その1つのオブジェクトのみを参照する等価メソッドとハッシュメソッドを作成できます(Eclipseでは、等価メソッドとハッシュメソッドを簡単に作成できます)。これにより、新しいオブジェクトは元のオブジェクトとまったく同じように保存、並べ替え、および取得され、プロパティを使用して残りのアイテムを格納します。
私がそれをするとき、ほとんどの場合、そこにも行くいくつかのメソッドがあり、それを知る前に、ずっとそこにあるはずであるが認識されていない本格的なオブジェクトと、大量のゴミがある私のコードからの要因。
それをより「ベイビーステップ」にするために、私はしばしば元のクラスに含まれる新しいクラスを作成します-そのようにスコープすることが理にかなっている場合は、メソッド内にクラスを含めることさえあります-そして私はそれを移動しますそれがファーストクラスのクラスであることがより明確になるにつれて、.
自分で作る:
Map<Object, List<Object>> multiMap = new HashMap<Object, List<Object>>();
たす:
public void add(String key, Object o) {
List<Object> list;
if (multiMap.containsKey(key)) {
list = multiMap.get(key);
list.add(o);
} else {
list = new ArrayList<Object>();
list.add(o);
multiMap.put(key, list);
}
}
マルチマップおよび類似のそのようなコレクションについては、 Googleコレクションライブラリ を参照してください。組み込みのコレクションは、これを直接サポートしていません。
あなたが探しているのは Multimap です。 google collections api は、これの素晴らしい実装と、使用することを学ぶ価値のある他の多くを提供します。強くお勧めします!
MultiMap と呼ばれるものを使用する必要があります。これは厳密にはマップではありませんが、別のAPIです。 Map <K、List <V >>とほぼ同じですが、entrySet()やvalues()などのメソッドはありません。
シンプル。の代わりに Hashtable<Key, Value>
、 使用する Hashtable<Key, Vector<Value>>
。
GoogleのGuavaライブラリなしのコードを以下に示します。これは、キーとしてダブル値に使用され、ソートされた順序です
Map<Double,List<Object>> multiMap = new TreeMap<Double,List<Object>>();
for( int i= 0;i<15;i++)
{
List<Object> myClassList = multiMap.get((double)i);
if(myClassList == null)
{
myClassList = new ArrayList<Object>();
multiMap.put((double) i,myClassList);
}
myClassList.add("Value "+ i);
}
List<Object> myClassList = multiMap.get((double)0);
if(myClassList == null)
{
myClassList = new ArrayList<Object>();
multiMap.put( (double) 0,myClassList);
}
myClassList.add("Value Duplicate");
for (Map.Entry entry : multiMap.entrySet())
{
System.out.println("Key = " + entry.getKey() + ", Value = " +entry.getValue());
}
Googleコレクションとは別に、MultiMap用の Apache Commons Collection オブジェクトがあります。