繁体   English   中英

Java中的多值哈希表

[英]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 谷歌收藏api提供了一个很好的实现,以及其他值得学习使用的东西。 强烈推荐!

您需要使用称为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM