Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug in HashMap / ArrayList or wrong code? [duplicate]

Tired up with trying to resolve the problem with this code:

public class MapTest {
    static class T{
        static class K{}
    }
    static Map<List<T.K>, List<String>> map = new HashMap<>();
    static List<String> test(List<T.K> list, String s){
        List<String> l = map.get(list);
        if (l == null){
            l = new ArrayList<String>();
            System.out.println("New value()");
            map.put(list, l);
        }
        l.add(s);
        return l;       
    }
    public static void main(String s[]){        
        ArrayList<T.K> list = new ArrayList<T.K>();
        test(list, "TEST");
        list.add(new T.K());
        List<String> l = test(list, "TEST1");
        System.out.println(l.size());
    }
}

It should create a new list-value for the map only once, but output is as follows:

New value
New value
1

it is something wrong happen with hashcode of the list after I insert value in it. I expect "new value" show up only once, and size will be 2, not 1. is it just JVM problem or something more general? mine one is Oracle JVM 1.8.0_65

like image 973
Павел Avatar asked Jan 27 '26 07:01

Павел


2 Answers

The hashcode of the list object changes when you put an item in it. You can see how the hashcode is calculated in the ArrayList.hashCode documentation.

In general, using a mutable object as the key for a map isn't going to work well. Per the Map documentation:

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.

Thus, when you add the list to the map a second time, the map doesn't see it as being "equal" to the first list (since it isn't according to .equals), so it adds it again.

If you want a map where keys are looked up by identity rather than by value, you can use the IdentityHashMap class.

like image 31
Joni Avatar answered Jan 28 '26 21:01

Joni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!