Why does my HashMap have a duplicate?

We have a class called Subscriber that extends "HashMap". We have many instances of this class listed, and each instance has a set of entries set to the map, one of which is "status".

Our program updates the status value by calling a method on the subscriber that takes a simple step into the HashMap.

Our program can run for days (weeks) without any problems, but sometimes we see strange behavior in some other parts of the system that uses data from HashMap. To us, this is like a duplicate key in one or more Subscriber instances.

We manage to dump the jmap, and based on the dump, it looks at me that we have a "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 am I reading VisualVM wrong?

+3


source to share


1 answer


Apart from the threading issue, there is a clear path 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 essentially makes the map keys mutable, so they can be changed after they are added to the map.

While this may not be the problem you are having (a multithreading problem is much more likely), it is the real answer to the question. Why does my HashMap have a duplicate key?

+1


source







All Articles