How come my HashMap have a duplicate key?

274 views Asked by At

We have a class named Subscriber, that extends "HashMap". We have many instances of this class in a list, and each instance has a set of entries set to the map, one of these are "status".

Our program is updating the "status" value by calling a method on the Subscriber, that does a simple put to the HashMap.

Our program can be running for multiple days (weeks) without any issues, but some times we have seen strange behaviour in some other parts of the system, that uses data from the HashMap. For us, it looks like there is a duplicate key in one or more of the Subscriber instances.

We manage to create a jmap dump, and based on the dump it looks for me that we have the "status" set twice when I look at the dump in VisualVM.

Screenshot of VisualVM

We are currently running Java version: 1.7.0_25 (Oracle)

How is this possible? Or do I read the VisualVM wrong?

1

There are 1 answers

2
OldCurmudgeon On

Apart from threading issue there is a clear route to this result:

class Key implements CharSequence {

    private byte[] key;

    public Key(String key) {
        // Take a copy of the bytes of the string.
        this.key = key.getBytes();
    }

    @Override
    public int length() {
        return key.length;
    }

    @Override
    public char charAt(int index) {
        return (char) key[index];
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        return new Key(new String(key).substring(start, end));
    }

    // Allow the key to change.
    public void setKey(String newValue) {
        key = newValue.getBytes();
    }

    @Override
    public String toString() {
        return new String(key);
    }
}

public void test() {
    Map<CharSequence, String> testMap = new HashMap<>();
    Key aKey = new Key("a");
    Key bKey = new Key("b");
    testMap.put(aKey, "a");
    testMap.put(bKey, "b");
    bKey.setKey("a");
    System.out.println(testMap.keySet());
}

This is essentially making the keys of the map mutable so they can be changed after they are added to the map.

Although this may not be the problem you are facing (a multi-threading issue is much more likely) this is a real answer to the question How come my HashMap have a duplicate key?.