Java中的多值哈希表

25 java collections hashtable map multimap

是否可以在哈希表中为同一个键设置多个值?如果没有,你能建议任何可以使用的类或接口吗?

Mic*_*ers 21

不,这就是哈希表的想法.

但是,您既可以滚你自己有Map<YourKeyObject, List<YourValueObject>>一些实用方法创建列表,如果它不存在,或者使用类似的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]"
Run Code Online (Sandbox Code Playgroud)

请注意,这与家庭烘焙解决方案Multimap并不完全相同 ; Hashtable同步所有方法,但Multimap没有这样的保证.这意味着如果在多个线程上使用它,使用a Multimap可能会导致问题.如果您的地图仅在一个线程上使用,那么它将没有任何区别(您应该使用而不是反正).HashMapHashtable


Eri*_*ric 11

哈希表的值是Object,因此您可以存储List

  • 这就是你想要的.+1 (2认同)

kdg*_*ory 7

而不是给出另一个多重映射答案,我会问你为什么要这样做?

多个值是否相关?如果是,那么创建一个数据结构来保存它们可能会更好.如果不是,那么使用单独的地图可能更合适.

您是否将它们保持在一起,以便您可以根据密钥对它们进行迭代?您可能希望寻找替代索引数据结构,如SkipList.


coo*_*ird 7

在哈希表中,可以使用键/值对来存储信息.

在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);
}
Run Code Online (Sandbox Code Playgroud)

在尝试将多个值("World","Mom")包含到单个键("Hello")中时,我们最终得到以下结果来打印以下内容中的条目Hashtable:

Answer=42
Hello=Mom
Run Code Online (Sandbox Code Playgroud)

键/值对"Hello""World"不在Hashtable- 只有第二个"Hello"和" Mom"条目在Hashtable.这表明一个人不能将多个值与a中的单个关联关联Hashtable.


这里真正需要的是一个multimap,它允许将多个值关联到一个键.

多图的一个实现Multimap来自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);
}
Run Code Online (Sandbox Code Playgroud)

这类似于上面使用的示例Hashtable,但行为完全不同 - a Multimap允许将多个值关联到单个键.执行上述代码的结果如下:

Answer=42
Hello=Mom
Hello=World
Run Code Online (Sandbox Code Playgroud)

可以看出,对于"Hello"密钥,它的值"Mom""World"与之相关联.Hashtable与之不同的是,它不会丢弃其中一个值并将其替换为另一个值.的Multimap是能够坚持到多个值的每个关键.


Jon*_*nik 5

正如其他人指出的那样,没有.相反,请考虑使用Multimap可以为同一个键映射许多值的a .

谷歌集合(更新:番石榴)库包含一个实现,并可能是你最好的选择.

编辑:当然你可以像Eric建议的那样做,并将Collection作为值存储在你的Hashtable(或更普遍的Map)中,但这意味着自己编写不必要的样板代码.使用Google Collections这样的库时,会为您处理低级别的"管道".看看这个很好的例子,说明如何使用Multimap而不是vanilla Java Collections类简化代码.


Cam*_*ium 5

只做你自己的:

Map<Object, List<Object>> multiMap = new HashMap<Object, List<Object>>();
Run Code Online (Sandbox Code Playgroud)

加上:

  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);
    }
  }
Run Code Online (Sandbox Code Playgroud)