I've experienced some really spooky TreeMap behavior and I've had some trouble narrowing down a small test case, so bear with me.
I want to read a large number of key-value pairs into a Map, from a file provided at runtime. I'm using a custom key class. Later, when I go to pull entries back out, I find that one or more of them are missing. Using a debugger and some test cases, I've determined that the missing entry(ies) are definitely disappearing during the read phase, but I'm not sure what's causing it.
Basically:
Map<MyKey,Double> map = new TreeMap<MyKey,Double>();
map.put(key1,value1);
// ... put another ~500 entries into the map ...
assertTrue(map.containsKey(key1)); // passes
if (!map.containsKey(keyN)) {
map.put(keyN, valueN); // this code executes
}
assertTrue(map.containsKey(key1)); // FAILS
...So essentially, adding a brand new key to the map causes an unrelated entry to fall out of it.
- If I just add key1 and keyN alone, key1 remains in the map -- the intervening 500 entries are somehow important
- If I remove one or two arbitrary keys from 2..(N-1), key1 is still booted out when keyN is added
- If I remove a large range of keys from 2..(N-1), key1 remains when keyN is added, but falls out when (say) keyQ is added, ~300 keys further down the line
- Unfortunately the size of the map when keyN kicks out key1 is not the same as the size of the map when keyQ kicks out key1, so it's probably not a limited-size issue
- If I use a HashMap instead, key1 remains in the map
- Custom key class MyKey uses the same logic for Comparable, equals, and hashCode.
I was initially using TreeMap because I expect to be using large datasets, and TreeMap is a little more memory-efficient. HashMap will be a fine alternative, but it's still alarming to see TreeMap behave this way -- anyone have thoughts on what's going on here?