防止 HashMap/HashTable 中重复 <Key,Value> 对的 Java 代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4415803/
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-14 17:13:48  来源:igfitidea点击:

Java code to Prevent duplicate <Key,Value> pairs in HashMap/HashTable

java

提问by Deepak

I have a HashMap as below (assuming it has 10,0000 elements)

我有一个 HashMap 如下(假设它有 10,0000 个元素)

HashMap<String,String> hm = new HashMap<String,String>();
hm.put("John","1");
hm.put("Alex","2");
hm.put("Mike","3");
hm.put("Justin","4");
hm.put("Code","5");

HashMap<String,String> hm = new HashMap<String,String>();
hm.put("John","1");
hm.put("Alex","2");
hm.put("Mike","3");
hm.put("Justin","4");
hm.put("Code","5");

==========================
    Expected Output     
==========================  

Key = John",Value = "1"
Key = Alex",Value = "2"
Key = Mike",Value = "3"
Key = Justin",Value = "4"
Key = Code",Value = "5"
===========================

Key = John",Value = "1"
Key = Alex",Value = "2"
Key = Mike",Value = "3"
Key = Justin",Value = "4"
Key = Code",Value = "5"
============================

I need Java code to prevent Addition of Duplicate <Key,Value> Pairsin HashMap such
that below conditions are staisfied.
1> hm.put("John","1"); is not accepted/added again in the Map
2> hm.put("John","2"); is not accepted/added again in the Map

我需要Addition of Duplicate <Key,Value> Pairs在 HashMap 中使用Java 代码来阻止
以下条件。
1> hm.put("John","1"); is not accepted/added again in the Map
2>hm.put("John","2"); is not accepted/added again in the Map

Hope its clear. Java code provided will be appreciated.(generic solution needed since i can add any duplicate to the existing map)

希望它清楚。提供的 Java 代码将不胜感激。(需要通用解决方案,因为我可以向现有地图添加任何副本)

采纳答案by khachik

You can wrap HashMapin a class, which delegates put, get, and other methods you use from HashMap. This method is wasteful but safe, since it doesn't depend on the internal implementation of HashMap, AbstractMap. The code below illustrates put, getdelegating:

你可以用HashMap一个类,它代表putget以及其他的方法你使用HashMap。这种方法是一种浪费,但安全的,因为它不依赖于内部实现HashMapAbstractMap。下面的代码说明了putget委托:

    public class Table {
       protected java.util.HashMap<String, Integer> map = 
             new java.util.HashMap<String, Integer>();

       public Integer get(String key) { return map.get(key); }

       public Integer put(String key, Integer value) {
          if (map.containsKey(key)) {
           // implement the logic you need here.
           // You might want to return `value` to indicate
           // that no changes applied
           return value;
          } else {
            return map.put(key, value);
          }
       }
       // other methods goes here
    }

Another option is to make a class which extends HashMap, and depend on its internal implementation. Java 1.6 sources shows that putis called only in putAllin HashMap, so you can simply override putmethod:

另一种选择是创建一个扩展类HashMap,并依赖于其内部实现。Java 1.6 源代码显示put仅在putAllin 中调用HashMap,因此您可以简单地覆盖put方法:

    public class Table extends java.util.HashMap<String, Integer> {
       public Integer put(String key, Integer value) {
          if (containsKey(key)) {
           // implement the logic you need here.
           // You might want to return `value` to indicate
           // that no changes applied
           return value;
          } else {
            return super.put(key, value);
          }
       }
    }

Another option is similar to the first, and can make an utility method in your class which contains the HashMapinstance and call that method wherever you need put something to your map:

另一个选项与第一个类似,可以在包含HashMap实例的类中创建一个实用程序方法,并在需要将某些内容放入地图的任何位置调用该方法:

public final Integer putToMap(String key, String value) {
   if(this.map.containsKey(key)) {
      return value;
   } else {
      return this.map.put(key, value);
   }
}

This is an "inline" equivalent of checking manually.

这相当于手动检查的“内联”。

回答by sushil bharwani

see even if u write same key values multiple times you will just have unique set of pairs. Check that by either iterating or by doing hm.size();

看看即使您多次写入相同的键值,您也只会拥有一组唯一的对。通过迭代或执行 hm.size();

回答by Matthew Flaschen

if(hm.put("John","1") != null)
{
  // "John" was already a key in the map.  The sole value for this key is now "1".
}

回答by Paul A. Hoadley

I note that you clarify the question by suggesting you might have "100000000 elements". You still won't have duplicates in the HashMap, because, as two other posters have pointed out, you can't get duplicate keys in a Map. I'm still not sure we understand the question, though, as it's not at all clear how you expected to generate the block titled "Output", or what you intend to do with it.

我注意到你通过暗示你可能有“100000000 个元素”来澄清这个问题。您仍然不会HashMapMap. 不过,我仍然不确定我们是否理解这个问题,因为完全不清楚您希望如何生成名为“输出”的块,或者您打算用它做什么。

回答by InsertNickHere

List<Object> yourElements = new ... // 10000000
for(Object O : yourElements) {
 if(myMap.get(O.key)==null) {
    myMap.put(O.key,O);
 }
}

回答by deepa

List<String> keys = new ArrayList<String>(); (1000000)
List<String> values = new ArrayList<String>(); (1000000)
Map<String, String> map = new HashMap<String, String>();
int i =0;
for(String key : keys){
  String returnedValue = map.put(key, values.get(i));
  if(returnedValue!=null){
         map.put(key, returnedValue);
         system.out.println("Duplicate key trying to be entered with new value so   reverting the duplicate key ="+key+"new Value"+values.get(i));
  }
}

回答by Ahmed salah

This may be old question but I thought to share my experience with this. As others pointed out you can't have the same element in a HashMap. By default HashMap will not allow this but there are some cases that you could end up with two or more elements are almost alike that you do not accept but HashMap will. For example, the following code defines a HashMap that takes an array of integers as a key then add :

这可能是个老问题,但我想分享我的经验。正如其他人指出的那样,您不能在 HashMap 中拥有相同的元素。默认情况下 HashMap 不允许这样做,但在某些情况下,您可能最终会得到两个或多个几乎相同但您不接受但 HashMap 的元素。例如,下面的代码定义了一个 HashMap,它将一个整数数组作为键,然后添加:

HashMap<int[], Integer> map1 = new HashMap<>();
int[] arr = new int[]{1,2,3};
map1.put(arr, 4);
map1.put(arr, 4);
map1.put(arr, 4);

At this point, the HashMap did not allow dublicating the key and map1.size()will return 1. However, if you added elements without creating the array first things will be different:

此时,HashMap 不允许复制键map1.size()并将返回 1。但是,如果您在不创建数组的情况下添加元素,则情况会有所不同:

HashMap<int[], Integer> map2 = new HashMap<>();
map2.put(new int[]{4,5,6}, 6);
map2.put(new int[]{4,5,6}, 6);
map2.put(new int[]{4,5,6}, 6);

This way, the HashMap will add all the three new elements so the map2.size()will return 3 and not 1 as expected.

这样,HashMap 将添加所有三个新元素,因此map2.size()将按预期返回 3 而不是 1。

The explanation is that with the first map I created the object arr once and tried to add the same object 3 times which HashMap does not allow by default so only the last usage will be considered. With the second map, however, evey time I recreate a new object on the stack. The three objects created are different and separated thought the three of them have the same data but they are different. That's why HashMap allowed them as different keys.

解释是,在第一个映射中,我创建了对象 arr 一次,并尝试添加相同的对象 3 次,HashMap 默认不允许,因此只考虑最后一次使用。然而,对于第二张地图,我每次都会在堆栈上重新创建一个新对象。创建的三个对象不同而分开,认为它们三个具有相同的数据但它们是不同的。这就是 HashMap 允许它们作为不同键的原因。

Bottom line, you don't need to prevent HashMap from adding dublicated keys because it won't by design. However, you have to watch out how you define these keys because the fault may be on your side.

最重要的是,您不需要阻止 HashMap 添加重复的键,因为它不会被设计。但是,您必须注意如何定义这些键,因为问题可能出在您这边。