【发布时间】:2013-01-15 21:20:03
【问题描述】:
我遇到了一些非常令人毛骨悚然的 TreeMap 行为,并且在缩小小测试用例范围时遇到了一些麻烦,请耐心等待。
我想从运行时提供的文件中将大量键值对读入 Map。我正在使用自定义键类。后来,当我去拉回条目时,我发现其中一个或多个丢失了。使用调试器和一些测试用例,我确定丢失的条目在读取阶段肯定会消失,但我不确定是什么原因造成的。
基本上:
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
...所以本质上,向地图添加一个全新的键会导致一个不相关的条目从其中脱落。
- 如果我只添加 key1 和 keyN,key1 会保留在映射中 - 中间的 500 个条目在某种程度上很重要
- 如果我从 2..(N-1) 中删除一个或两个任意键,则在添加 keyN 时 key1 仍会启动
- 如果我从 2..(N-1) 中删除大范围的键,则在添加 keyN 时 key1 仍然存在,但在添加(例如)keyQ 时会丢失,大约 300 个键会进一步向下
- 很遗憾,keyN 踢出 key1 时的地图大小不与 keyQ 踢出 key1 时的地图大小相同,所以这可能不是限制大小的问题
- 如果我改用 HashMap,key1 会保留在地图中
- 自定义键类 MyKey 对 Comparable、equals 和 hashCode 使用相同的逻辑。
我最初使用 TreeMap 是因为我希望使用大型数据集,而 TreeMap 更节省内存。 HashMap 将是一个不错的选择,但看到 TreeMap 以这种方式运行仍然令人担忧——有人对这里发生的事情有想法吗?
【问题讨论】:
-
同意史蒂夫郭的观点。注释掉您的 compareTo/equals/hashCode 实现并再次运行您的测试,看看您是否遇到同样的问题。
标签: java map key treemap comparable