[英]Multi-valued hashtable in Java
是否可以在哈希表中為同一個鍵設置多個值? 如果沒有,你能建議任何可以使用的類或接口嗎?
不,這就是哈希表的想法。
但是,您可以使用Map<YourKeyObject, List<YourValueObject>>
以及一些用於創建列表的實用程序方法(如果它不存在)來滾動您自己的方法,或者使用類似Google Collections中的Multimap
。
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
並不完全等同於自制解決方案; Hashtable
同步其所有方法,而Multimap
沒有這樣的保證。 這意味着如果在多個線程上使用Multimap
,使用Multimap
可能會導致問題。 如果你的地圖只在一個線程上使用,它就沒有區別(你應該使用HashMap
而不是Hashtable
)。
哈希表的值是Object,因此您可以存儲List
而不是給出另一個多重映射答案,我會問你為什么要這樣做?
多個值是否相關? 如果是,那么創建一個數據結構來保存它們可能會更好。 如果不是,那么使用單獨的地圖可能更合適。
您是否將它們保持在一起,以便您可以根據密鑰對它們進行迭代? 您可能希望尋找替代索引數據結構,如SkipList。
在哈希表中,可以使用鍵/值對來存儲信息。
在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
- 只有第二個"Hello"
和“ Mom
”條目在Hashtable
。 這表明不能將多個值與Hashtable
的單個鍵相關聯。
這里真正需要的是一個multimap ,它允許將多個值關聯到一個鍵。
多圖的一個實現是來自Google Collections的 Multimap
:
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
不同,它不會丟棄其中一個值並將其替換為另一個值。 Multimap
能夠為每個鍵保留多個值。
正如其他人指出的那樣,沒有。 相反,請考慮使用Multimap
,它可以為同一個鍵映射許多值。
Google Collections ( 更新 : Guava )庫包含一個實現,可能是您最好的選擇。
編輯 :當然你可以像Eric建議的那樣做,並將Collection作為值存儲在你的Hashtable(或更普遍的Map)中,但這意味着自己編寫不必要的樣板代碼。 使用Google Collections這樣的庫時,會為您處理低級別的“管道”。 查看使用Multimap而不是vanilla Java Collections類簡化代碼的簡單示例 。
沒有一個答案表明我先做什么。
我在OO能力方面取得的最大跳躍是當我決定總是創建另一個類時,它似乎甚至可能有點用處 - 這是我從遵循該模式學到的東西之一。
幾乎所有時間,我發現我試圖放入哈希表的對象之間存在關系。 通常情況下,課堂上有空間 - 甚至是一兩種方法。
事實上,我經常發現我甚至不想要一個HashMap類型結構 - 一個簡單的HashSet就可以了。
您作為主鍵存儲的項目可以成為新對象的標識 - 因此您可以創建僅引用該對象的equals和hash方法(eclipse可以輕松地為您創建equals和hash方法)。 這樣,新對象將像原始對象一樣保存,排序和檢索,然后使用屬性來存儲其余項目。
大多數時候,當我這樣做時,我發現有一些方法可以去那里,在我知道它之前我有一個完整的對象應該一直存在但我從來沒有認識到,和一堆垃圾我的代碼中的因素。
為了使它更像是一個“寶貝步驟”,我經常創建我原始類中包含的新類 - 有時我甚至在方法中包含類,如果它以這種方式調整范圍 - 然后我移動它因為它變得更加清晰,它應該是一流的課程。
做你自己的:
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 Collections Library 。 內置集合沒有直接支持。
您需要使用稱為MultiMap的東西。 這不是嚴格意義上的Map,但它是一個不同的API。 它與Map <K,List <V >>大致相同,但您不會使用entrySet()或values()等方法。
簡單。 而不是Hashtable<Key, Value>
,使用Hashtable<Key, Vector<Value>>
。
以下代碼沒有谷歌的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 Collections之外,還有一個用於MultiMap的apache Commons Collection對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.