ハッシュテーブルで同じキーに対して複数の値を持つことは可能ですか? そうでない場合は、使用できるそのようなクラスまたはインターフェイスを提案できますか?
13 に答える
いいえ、それは一種のハッシュ テーブルの考え方です。
Map<YourKeyObject, List<YourValueObject>>
ただし、リストが存在しない場合はリストを作成するためのa およびいくつかのユーティリティ メソッドを使用して独自のロールを作成するかMultimap
、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
に同等ではないことに注意してください。すべてのメソッドを同期しますが、そのような保証はしません。これは、複数のスレッドで使用している場合、使用すると問題が発生する可能性があることを意味します。マップが 1 つのスレッドでのみ使用されている場合、違いはありません (とにかく代わりに使用する必要がありました)。Hashtable
Multimap
Multimap
HashMap
Hashtable
ハッシュテーブルの値はオブジェクトなので、リストを保存できます
さらに別の multipmap の答えを出すのではなく、なぜこれをしたいのか尋ねますか?
複数の値は関連していますか? はいの場合は、それらを保持するためのデータ構造を作成することをお勧めします。そうでない場合は、別のマップを使用する方が適切かもしれません。
キーに基づいて反復できるように、それらをまとめていますか? SkipList など、別のインデックス データ構造を探すこともできます。
自分で作成するだけです。
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);
}
}
他の人が指摘したように、いいえ。代わりにMultimap
、同じキーに多くの値をマップできる を使用することを検討してください。
Google Collections ( update : Guava ) ライブラリには 1 つの実装が含まれており、おそらくこれが最善の策です。
編集: もちろん、 Eric が示唆するように行うことができ、コレクションを Hashtable (またはより一般的には Map) に値として保存できますが、それは不要なボイラープレート コードを自分で作成することを意味します。Google Collections のようなライブラリを使用すると、低レベルの「配管」が処理されます。通常の Java Collections クラスの代わりに Multimap を使用することで、コードがどのように単純化されるかを示すこの素晴らしい例を確認してください。
私が最初に何をするかを示す答えはありませんでした。
オブジェクト指向能力に関して私がこれまでに達成した最大のジャンプは、少しでも役立つかもしれないと思われるときに、常に別のクラスを作成することに決めたときでした。これは、そのパターンに従って学んだことの 1 つです。
ほとんどの場合、ハッシュ テーブルに配置しようとしているオブジェクト間に関係があることがわかります。多くの場合、1 つまたは 2 つのメソッドでさえ、クラスの余地があります。
実際、HashMap 型の構造さえ必要としないことがよくあります。単純な HashSet で十分です。
主キーとして保存しているアイテムは、新しいオブジェクトの ID になる可能性があります。そのため、その 1 つのオブジェクトのみを参照する equals および hash メソッドを作成できます (Eclipse を使用すると、equals および hash メソッドを簡単に作成できます)。そうすれば、新しいオブジェクトは元のオブジェクトとまったく同じように保存、並べ替え、取得し、プロパティを使用して残りのアイテムを保存します。
ほとんどの場合、そこにもいくつかのメソッドがあり、気が付く前に、ずっとそこにあったはずなのに認識できなかった本格的なオブジェクトがあり、大量のゴミがあります。私のコードの要因。
より「ベイビーステップ」にするために、元のクラスに含まれる新しいクラスを作成することがよくあります。そのようにスコープすることが理にかなっている場合は、メソッド内にクラスを含めることもあります。それが一流のクラスであるべきであることがより明確になるにつれて。
マルチマップや同様のコレクションについては、 Google コレクション ライブラリを参照してください。組み込みコレクションはこれを直接サポートしていません。
あなたが探しているのはMultimapです。google collections apiは、この機能の優れた実装と、使用方法を学ぶ価値のある他の多くの機能を提供します。強くお勧めします!
単純。の代わりに
Hashtable<Key, Value>
、 を使用しますHashtable<Key, Vector<Value>>
。
MultiMapと呼ばれるものを使用する必要があります。これは厳密にはマップではありませんが、別の API です。Map<K, List<V>> とほぼ同じですが、entrySet() や values() などのメソッドはありません。
Google の Guava ライブラリを使用しない次のコード。キーとソートされた順序として double 値に使用されます
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オブジェクトがあります。