增加HashMap中的整数

时间:2010-11-25 13:08:22

标签: java pointers reference hashmap

我是否必须返回该对象,然后再添加一个新对象?或者我可以直接递增?

Integer temp = myMap.get(key);
temp++;
myMap.put(key, temp);

没有办法做到这一点(这不起作用):

myMap.get(key)++;

12 个答案:

答案 0 :(得分:22)

这是完成这项工作的最短代码。

myMap.put(key, myMap.get(key) + 1)

我认为不会太长。

答案 1 :(得分:20)

您可以使用可变整数,例如AtomicInteger。

Map<Key, AtomicInteger> myMap = new HashMap<Key, AtomicInteger>();
myMap.get(key).incrementAndGet();

或者你可以使用支持集合中原语的Trove4j。

TObjectIntHashMap<Key> myMap;
myMap.increment(key); 

答案 2 :(得分:17)

在Java 8中,Map上有一些新方法可以与lambdas一起使用来解决这个问题。第一种选择,compute

a.compute(key, (k, v) -> v+1);

请注意,这仅适用于为所有可能的键初始化哈希的情况。

如果无法保证,您可以将上述代码更改为:

a.compute(key, (k, v) -> v == null ? 1 : v + 1);

或使用merge方法(我更喜欢):

a.merge(key, 1, (a, b) -> a + b);

也许有更多基于lambda的方法我不知道。

答案 3 :(得分:13)

  

我是否必须返回该对象,然后再添加一个新对象?

只要你使用Integer包装类是的,因为它是不可变的。您可以使用可变包装类,即使是具有increment()方法的类。但是,您失去了对值使用自动装箱和自动装箱的能力。

答案 4 :(得分:7)

您不能直接递增它,因为它是immutable。你必须增加它并将新对象放回去。

自动拳击也在这里干扰。实际上发生的事情类似于:

Integer i1 = getFromMap();
i1 = Integer.valueOf(++ i1.intValue());

所以这里你的参考指向一个新对象。您必须将该对象放回到相同的键下的地图中。

答案 5 :(得分:3)

由于Integer是不可变的,是的,你必须这样做。 如果你真的想直接增加它,你必须编写自己的可变类。

答案 6 :(得分:2)

如果你不得不这样做两次以上,你宁愿创建一个小类,如:

public class MappedCounter {

    private Map<String, Integer> map = new HashMap<String, Integer>();

    public void addInt(String k, int v) {
        if (!map.containsKey(k))    map.put(k, v);
        else                map.put(k, map.get(k) + v);
    }

    public int getInt(String k) {
        return map.containsKey(k) ? map.get(k) : 0;
    }

    public Set<String> getKeys() {
        return map.keySet();
    }
}

答案 7 :(得分:0)

首先:注意拆箱:temp来自Integer类型。但是为int实现了++的操作。所以temp被取消装箱以输入int。这意味着如果temp为null,则运行NullPointerException。

你必须像在第一个代码块中描述的那样去做。

答案 8 :(得分:0)

我使用下面的代码并且它可以工作但是在开始时你需要定义一个BiFunction来描述操作以1递增。

public static Map<String, Integer> strInt = new HashMap<String, Integer>();

public static void main(String[] args) {
    BiFunction<Integer, Integer, Integer> bi = (x,y) -> {
        if(x == null)
            return y;
        return x+y;
    };
    strInt.put("abc", 0);


    strInt.merge("abc", 1, bi);
    strInt.merge("abc", 1, bi);
    strInt.merge("abc", 1, bi);
    strInt.merge("abcd", 1, bi);

    System.out.println(strInt.get("abc"));
    System.out.println(strInt.get("abcd"));
}

输出

3
1

答案 9 :(得分:0)

为了完整性,在Java 8中有一个longAdder,与AtomicInteger相比带来了一些好处(http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html

{{1}}

答案 10 :(得分:-1)

这应该有效

        // If the key you want to add does not exist then add it as a new key
        // And make the value 1
        if (map.get(key) == null) {
            map.put(key, 1);
        } else {
            // If the key does exist then replace the key's value with it's
            // Original value plus one
            map.put(key, map.get(key) + 1);
        }

答案 11 :(得分:-1)

发现这是避免NPE的最佳方法。

Map<Integer, Integer> map = new HashMap<>();
map.put(5, map.getOrDefault(5, 0) + 1);
System.out.println(map.get(5));

Output:
1
相关问题