【发布时间】:2022-10-13 00:17:42
【问题描述】:
我有无数带有自定义键和比较器的地图。我注意到当我使用类似的代码创建地图时
var map = TreeMap<>( someCustomComparator );
然后,我使用如下代码创建了一个不可变(且小而快)的副本:
map = Map.copyOf( map );
然后map.get( similarObject ) 无法检索someObject,即使someObject 和similarObject 在比较器someCustomComparator 下比较相等(“具有相同的等价类”)。
调试 API 我发现 Map.copyOf 返回一个使用 Object::equals 比较键的映射实现,即它不使用用于构造原始映射的比较器(在我的示例中,这将是 someCustomComparator)。显然,当someObject 和similarObject 不是同一个对象但在someCustomComparator 下具有相同的等价类但Object::equals 没有被覆盖时,这会产生奇怪的结果:
map.get( similarObject ) ==> someObject
在map = Map.copyOf( map ) 指令之前,以及
map.get( similarObject ) ==> null
在map = Map.copyOf( map ) 指令之后。这是我必须忍受的预期行为还是应该报告 Java 缺陷?
(注意some/similarObject 的类也实现了comparable,Map.copyOf 实现也忽略了这一点。)
(我认为这种行为在所有集合 copyOf 实现中都很常见。)
标签: java api dictionary copy comparator