Search code examples
javaatomic-long

The operator += is undefined for the argument type(s) int, AtomicLong


I have a Map as below -

ConcurrentHashMap<Long, AtomicLong> histogram = new ConcurrentHashMap<Long, AtomicLong>();

This map contains lot of key value pair. Putting the AtomicLong as the value was necessary so that is the reason I have put like that in that map.

So now if I am trying to iterate through ConcurrentHashMap that I mentioned above, it always give me error on this line-

buckets[i] += histogram.get(time);

as- The operator += is undefined for the argument type(s) int, AtomicLong

I am not sure how can I fix this problem? I cannot go back and change the data structure to all Integer instead of Long and AtomicLong.

So I need to find out how to make change in the below code so that it starts working. I was thinking of casting to Integer. But it was also not working.

Below is my code

private static void logHistogramInfo() {

    System.out.println("From Main Thread: " + histogram);

    int[] definition = { 0, 20, 40, 60, 80, 100 };
    int[] buckets = new int[definition.length];

    for (Long time : histogram.keySet()) {
        for (int i = definition.length - 1; i >= 0; i--) {
            if (time >= definition[i]) {
                      //error on the below line
                buckets[i] += histogram.get(time);
                break;
            }
        }
    }
    for (int i = 0; i < definition.length; i++) {
        String period = "";
        if (i == definition.length - 1) {
            period = "greater than " + definition[i] + "ms";
        } else {
            period = "between " + (definition[i] + 1) + " and " + definition[i + 1] + "ms";
        }
        System.out.println(buckets[i] + " came back " + period);
    }

}

Solution

  • The += operator was originally intended for use with the primitive data types (int, long...). Since these cannot be put in a map, the wrapper classes exists. When you use an Integer or Long with any arithmetic operator, these are automatically "unboxed" to their corresponding primitive type.

    However, there is no primitive type corresponding to any AtomicXYZ. You can, however, use any of the methods the Number class provides to get its value as a primitive, e.g. longValue() or intValue(). Note that the value of your atomic long can in principle be larger than the largest int (or Integer), so you may want to deal with the potential overflow in some way.

    [edit] Or you can use the get() method as assylias points out (which I was not aware of as I never used the atomic types before), which does the same thing as longValue() for AtomicLong (and the same thing as intValue() for AtomicInteger), as can be seen from its implementation.