当重复的键出现时,HashMap自定义覆盖值

3

我是Java的新手,我有一个哈希表,我需要将年龄作为键,计数作为值插入,即

         HashMap<Integer,Integer> hashMap = new HashMap<Integer, Integer>();
         hashMap.put(1,1);
         hashMap.put(2,1);
         hashMap.put(3,1);
         hashMap.put(1,1);  // whenever i insert this ,according to hashmap, it will override, but i want to customise like  the value should be incremented , ie the value of key 1 should be 2, again if i insert with  
         hashMap.put(1,1); // the value of key 1 should be 3.

我希望您可以在添加重复键时自定义覆盖值。我是通过以下方式完成的:
         if(hashMap.containsValue(1)){
             Integer i = hashMap.get(1);
             i++;
             hashMap.put(1, i);
         }else{
             hashMap.put(1, 1);
         }  

有比这更好的方法吗?请提供建议。

1
“最佳”方法与您的项目有关,因此很难建议一个“最佳”方法。但是,您可以创建一个包含您的HashMap的类,并且该类可以提供像getput这样的方法。然后在put方法中,如果键已经存在于映射中,则可以增加其值。 - Tom
1
你也可以使用Guava的Multiset,它快速简便,而且不需要重新发明轮子。 - biziclop
4个回答

1

有几种方法可以解决这个问题,你的方法可能是可行的。

例如,如果您想最小化put操作的数量,您可以创建一个可变的Counter类,它包装了一个整数(int primitive)并提供了一个增量方法(counter++)。然后您可以像这样使用它:

     Map<Integer, Counter> ageMap;
     Integer age = ....;
     if(ageMap.containsValue(age)){
         ageMap.get(age).increment();
     }else{
         ageMap.put(age, new Counter(1));
     } 

@SilentKnight 一个自定义类,你需要编写一个包装整数并提供增量方法的类。 - Puce

1
在Java 8中,您可以查看Map.computeIfPresent()方法:
hashMap.computeIfPresent(aKey, (k, v) -> v + 1);

0

技巧:

int[] ages=...;
HashMap<Integer,Integer> ageMap = new HashMap<Integer, Integer>();
for(int i = 0;i < ages.length; i++){
    if(ageMap.contains(ages[i])){
        ageMap.put(ages[i], ageMap.get(ages[i])+1);
    } else {
        ageMap.put(ages[i], 1);
    }
}

然后,ageMap 是从 ageage countMap

1
@Tom 是的,你说得对。我已经重新编辑了我的回答。 - SilentKnight

0
你可以创建一个继承自HashMap并重写put方法的MyHashMap类。或者,你可以将一个hashmap作为MyHashMap的私有字段,在MyHashMap的put方法中应用你已经编写好的代码。

3
不建议扩展HashMap,因为其语义差异较大,大多数操作都没有意义。最好创建一个自定义类来包装哈希映射。 - biziclop
1
我肯定也不建议这样做,但这是一种可能性。已更新答案并包括您的建议。 - EvenLisle
好的,我只是想让OP意识到他或她所拥有的不是一个地图,而是一个集合。 - biziclop
我同意你的建议,但是就挑剔一点而言:它被称为一个集合并不严格准确,对吧?因为他需要将计数与年龄关联起来。 - EvenLisle
1
这是一个元素重复次数大于1的集合。但你说得对,它们并不严格属于集合,而是袋子。 - biziclop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接