Java 具有重复键的映射实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1062960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:59:52  来源:igfitidea点击:

Map implementation with duplicate keys

javaduplicatesguavamultimap

提问by IAdapter

I want to have a map with duplicate keys.

我想要一张带有重复键的地图。

I know there are many map implementations (Eclipse shows me about 50), so I bet there must be one that allows this. I know it's easy to write your own map that does this, but I would rather use some existing solution.

我知道有很多地图实现(Eclipse 向我展示了大约 50 个),所以我敢打赌一定有一个允许这样做。我知道编写自己的地图来执行此操作很容易,但我宁愿使用一些现有的解决方案。

Maybe something in commons-collections or google-collections?

也许是在 commons-collections 或 google-collections 中?

采纳答案by nd.

You are searching for a multimap, and indeed both commons-collections and Guava have several implementations for that. Multimaps allow for multiple keys by maintaining a collection of values per key, i.e. you can put a single object into the map, but you retrieve a collection.

您正在搜索多图,实际上 commons-collections 和 Guava 都有几个实现。多重映射通过维护每个键的值集合来允许多个键,即您可以将单个对象放入映射中,但您检索一个集合。

If you can use Java 5, I would prefer Guava's Multimapas it is generics-aware.

如果您可以使用 Java 5,我更喜欢 Guava 的,Multimap因为它具有泛型意识。

回答by AlbertoPL

You could simply pass an array of values for the value in a regular HashMap, thus simulating duplicate keys, and it would be up to you to decide what data to use.

您可以简单地为常规 HashMap 中的值传递一组值,从而模拟重复的键,并且由您决定使用什么数据。

You may also just use a MultiMap, although I do not like the idea of duplicate keys myself.

您也可以只使用MultiMap,尽管我自己不喜欢重复键的想法。

回答by Priyank

Could you also explain the context for which you are trying to implement a map with duplicate keys? I am sure there could be a better solution. Maps are intended to keep unique keys for good reason. Though if you really wanted to do it; you can always extend the class write a simple custom map class which has a collision mitigation function and would enable you to keep multiple entries with same keys.

您能否解释一下您尝试使用重复键实现映射的上下文?我相信会有更好的解决方案。地图旨在保留唯一键是有充分理由的。虽然如果你真的想这样做;您始终可以扩展该类,编写一个简单的自定义地图类,该类具有碰撞缓解功能,并使您能够使用相同的键保留多个条目。

Note: You must implement collision mitigation function such that, colliding keys are converted to unique set "always". Something simple like, appending key with object hashcode or something?

注意:您必须实现碰撞缓解功能,以便将碰撞键转换为唯一的“始终”集。一些简单的事情,比如用对象哈希码或其他东西附加键?

回答by Mnementh

If you want iterate about a list of key-value-pairs (as you wrote in the comment), then a List or an array should be better. First combine your keys and values:

如果您想迭代键值对列表(如您在评论中所写),那么 List 或数组应该更好。首先结合您的键和值:

public class Pair
{
   public Class1 key;
   public Class2 value;

   public Pair(Class1 key, Class2 value)
   {
      this.key = key;
      this.value = value;
   }

}

Replace Class1 and Class2 with the types you want to use for keys and values.

将 Class1 和 Class2 替换为要用于键和值的类型。

Now you can put them into an array or a list and iterate over them:

现在您可以将它们放入数组或列表中并遍历它们:

Pair[] pairs = new Pair[10];
...
for (Pair pair : pairs)
{
   ...
}

回答by newacct

just to be complete, Apache Commons Collections also has a MultiMap. The downside of course is that Apache Commons does not use Generics.

为了完整起见,Apache Commons Collections 也有一个MultiMap。缺点当然是 Apache Commons 不使用泛型。

回答by cyberthanasis

If there are duplicate keys then a key may correspond to more than one value. The obvious solution is to map the key to a list of these values.

如果有重复的键,那么一个键可能对应多个值。显而易见的解决方案是将键映射到这些值的列表。

For example in Python:

例如在 Python 中:

map = dict()
map["driver"] = list()
map["driver"].append("john")
map["driver"].append("mike")
print map["driver"]          # It shows john and mike
print map["driver"][0]       # It shows john
print map["driver"][1]       # It shows mike

回答by Ravi Parekh

commons.apache.org

MultiValueMap class

回答by user668943

We don't need to depend on the Google Collections external library. You can simply implement the following Map:

我们不需要依赖 Google Collections 外部库。您可以简单地实现以下 Map:

Map<String, ArrayList<String>> hashMap = new HashMap<String, ArrayList>();

public static void main(String... arg) {
   // Add data with duplicate keys
   addValues("A", "a1");
   addValues("A", "a2");
   addValues("B", "b");
   // View data.
   Iterator it = hashMap.keySet().iterator();
   ArrayList tempList = null;

   while (it.hasNext()) {
      String key = it.next().toString();             
      tempList = hashMap.get(key);
      if (tempList != null) {
         for (String value: tempList) {
            System.out.println("Key : "+key+ " , Value : "+value);
         }
      }
   }
}

private void addValues(String key, String value) {
   ArrayList tempList = null;
   if (hashMap.containsKey(key)) {
      tempList = hashMap.get(key);
      if(tempList == null)
         tempList = new ArrayList();
      tempList.add(value);  
   } else {
      tempList = new ArrayList();
      tempList.add(value);               
   }
   hashMap.put(key,tempList);
}

Please make sure to fine tune the code.

请确保微调代码。

回答by frostbite

Learn from my mistakes...please don't implement this on your own. Guava multimap is the way to go.

从我的错误中吸取教训……请不要自行实施。番石榴多图是要走的路。

A common enhancement required in multimaps is to disallow duplicate keys-value pairs.

多映射所需的一个常见增强是禁止重复的键值对。

Implementing/changing this in a your implementation can be annoying.

在您的实现中实现/更改它可能很烦人。

In Guava its as simple as:

在番石榴中,它很简单:

HashMultimap<String, Integer> no_dupe_key_plus_val = HashMultimap.create();

ArrayListMultimap<String, Integer> allow_dupe_key_plus_val = ArrayListMultimap.create();

回答by Suresh Vadali

I had a slightly different variant of this issue: It was required to associate two different values with same key. Just posting it here in case it helps others, I have introduced a HashMap as the value:

我对这个问题有一个稍微不同的变体:需要将两个不同的值与相同的键相关联。只是将其发布在这里以防对其他人有帮助,我引入了一个 HashMap 作为值:

/* @param frameTypeHash: Key -> Integer (frameID), Value -> HashMap (innerMap)
   @param innerMap: Key -> String (extIP), Value -> String
   If the key exists, retrieve the stored HashMap innerMap 
   and put the constructed key, value pair
*/
  if (frameTypeHash.containsKey(frameID)){
            //Key exists, add the key/value to innerHashMap
            HashMap innerMap = (HashMap)frameTypeHash.get(frameID);
            innerMap.put(extIP, connName+":"+frameType+":"+interfaceName);

        } else {
            HashMap<String, String> innerMap = new HashMap<String, String>();
            innerMap.put(extIP, connName+":"+frameType+":"+interfaceName);
            // This means the key doesn't exists, adding it for the first time
            frameTypeHash.put(frameID, innerMap );
        }
}

In the above code the key frameID is read from a input file's first string in each line, the value for frameTypeHash is constructed by splitting the remaining line and was stored as String object originally, over a period of time the file started having multiple lines (with different values) associated with same frameID key, so frameTypeHash was overwritten with last line as the value. I replaced the String object with another HashMap object as the value field, this helped in maintaining single key to different value mapping.

在上面的代码中,关键frameID是从输入文件的每一行的第一个字符串中读取的,frameTypeHash的值是通过拆分剩余的行来构造的,并且最初存储为String对象,一段时间后文件开始具有多行(不同的值)与相同的 frameID 键关联,因此 frameTypeHash 被最后一行作为值覆盖。我用另一个 HashMap 对象替换了 String 对象作为值字段,这有助于维护单个键到不同值的映射。