Java中的多值哈希表

Java中的多值哈希表,java,collections,map,hashtable,multimap,Java,Collections,Map,Hashtable,Multimap,哈希表中同一个键可能有多个值吗?如果没有,您能推荐任何可以使用的类或接口吗?否。这就是哈希表的概念 但是,您可以使用映射和一些实用方法(如果列表不存在)来创建自己的列表,或者使用类似于from的方法 例子: String key=“你好”; Multimap myMap=HashMultimap.create(); myMap.put(键,1); myMap.put(键,5000); System.out.println(myMap.get(key));//打印“[1,5000]”或“[5000

哈希表中同一个键可能有多个值吗?如果没有,您能推荐任何可以使用的类或接口吗?

否。这就是哈希表的概念

但是,您可以使用
映射和一些实用方法(如果列表不存在)来创建自己的列表,或者使用类似于from的方法

例子:
String key=“你好”;
Multimap myMap=HashMultimap.create();
myMap.put(键,1);
myMap.put(键,5000);
System.out.println(myMap.get(key));//打印“[1,5000]”或“[5000,1]”
myMap=ArrayListMultimap.create();
myMap.put(键,1);
myMap.put(键,5000);
System.out.println(myMap.get(key));//始终打印“[15000]”

请注意,
Multimap
不是家庭烘焙解决方案的精确等效物;同步其所有方法,而
Multimap
不提供此类保证。这意味着如果在多个线程上使用
Multimap
,可能会导致问题。如果您的映射只在一个线程上使用,则不会有任何区别(而且您应该一直使用而不是
哈希表)。

哈希表的值是对象,因此您可以存储列表您需要使用名为。这不是一个严格意义上的映射,但是,它是一个不同的API。它与映射大致相同,但不会有entrySet()或values()之类的方法。

简单。而不是
Hashtable
,使用
Hashtable

有关多重映射和类似集合,请参阅。内置的集合并没有直接的支持。

正如其他人指出的,不是,而是考虑使用<代码> MultIMAP < /Cord>,它可以映射同一个键的许多值。

(更新:)库包含一个实现,可能是您最好的选择


编辑:当然,您可以这样做,并将集合作为值存储在哈希表(更一般地说是映射)中,但这意味着您需要自己编写不必要的样板代码。当使用像GoogleCollections这样的库时,它会为您提供底层的“管道”。请查看这篇文章,了解使用Multimap而不是vanilla Java Collections类如何简化代码。

与其给出另一个Multimap答案,不如问一下为什么要这样做

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


您是否将它们放在一起,以便可以基于密钥对它们进行迭代?您可能需要寻找一种替代的索引数据结构,如SkipList。

您要寻找的是一个。提供了一个很好的实现,以及许多值得学习使用的其他功能。强烈推荐

没有一个答案表明我首先会做什么

我在OO能力方面所取得的最大进步是当我决定总是在看起来可能有点用处的时候创建另一个类——这是我从遵循这种模式中学到的东西之一

几乎所有的时候,我都会发现我试图放入哈希表的对象之间存在着某种关系。通常,一个类甚至一两个方法都有空间

事实上,我经常发现我甚至不想要HashMap类型的结构——一个简单的HashSet就可以了

作为主键存储的项可以成为新对象的标识——因此您可以创建仅引用该对象的equals和hash方法(eclipse可以轻松地为您创建equals和hash方法)。这样,新对象将像原始对象一样进行保存、排序和检索,然后使用属性存储其余的项

大多数时候,当我这么做的时候,我发现有一些方法也在那里,在我意识到之前,我有一个完整的对象,它本来应该一直在那里,但我从来没有意识到,还有一堆垃圾因素从我的代码中


为了使它更像一个“婴儿步”,我经常创建包含在原始类中的新类——有时我甚至将该类包含在一个方法中,如果这样做有意义的话——然后我移动它,因为它变得更清楚,它应该是一个一流的类。

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

在Java中,类接受单个键的单个值。以下是尝试将多个值关联到单个键的示例:

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);
}
“Hello”
“World”
的键/值对不在
哈希表中,只有第二个
“Hello”
和“
Mom
”条目在
哈希表中。这表明在
哈希表中不能有多个值与单个键关联


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

多重映射的一个实现来自:

可以看到,对于
“Hello”
键,与之关联的
“Mom”
“World”
的值。与哈希表
不同,它不会丢弃其中一个值并用另一个值替换。
Multimap
可以为每个键保留多个值。

只需创建自己的:

Map<Object, List<Object>> multiMap = new HashMap<Object, List<Object>>();
Map multiMap=newhashmap();
加上:

  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);
    }
  }
public void add(字符串键,对象o){
名单;
if(多映射容器(键)){
list=multiMap.get(键);
列表。添加(o);
}否则{
列表=新的ArrayList();
列表。添加(o);
multiMap.put(键、列表);
}
}

除了谷歌收藏,还有一个对象
对于MultiMap

来说,下面的代码没有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());
}
Map multiMap=newtreemap();

对于(int i=0;iYes),可以存储列表,但不能只添加
Answer=42
Hello=Mom
Hello=World
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);
    }
  }
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());
}