Java 的哈希映射不允许自定义 equals/hashCode 有充分的理由吗?

问题描述 投票:0回答:1

ConcurrentHashMap
HashMap
正在使用关键实例的
equals()
/
hashCode()

几十年来,在很多情况下,我都错过了提供不同的 equals/hashCode 实现的可能性。无法做到这一点意味着您要么必须使用排序映射,它允许您设置

Comparator
,但代价是 SortedMap 的性能特征更差,或者您必须使用不同的对象作为键,即通过创建键提供自己的 equals/hashCode 实现的包装器实例。

在后一种情况下,需要为每个键创建另一个对象具有明显的内存和性能影响。 (在我正在查看的当前情况下,这意味着在高峰时间每秒创建数十万个额外的对象实例——这是性能最重要的地方。)

这似乎是一项微不足道且安全的更改,在需要的情况下具有巨大的性能优势。

.Net 从

 至少版本 1.1
开始为其 Dictionary 提供此功能。那么,Java 没有的原因有什么好的技术原因吗?

java hashmap concurrenthashmap
1个回答
1
投票

这被要求作为 Java 1.2.2 等的 RFE,但从未实施并最终关闭。 https://bugs.openjdk.org/browse/JDK-4269596

Joshua Bloch 在 1999 年的分析是:

在设计 Collections Framework 时,我们仔细考虑过是否要包含对自定义 equals/hashCode 方法的支持。最后,我们以增加复杂性和与其他设计决策不一致为由拒绝了它。特别是,List、Set 和 Map 对象可以独立于它们的表示进行比较的决定与对自定义 equals 方法的支持不一致。

此外,完全支持自定义 equals 方法可能有点矫枉过正。 99% 的情况下,当开发人员想要一个具有自定义 equals 方法的集合时,所需的 equals 方法是元素标识。这提出了一种替代解决方案,即提供一个或两个基于身份而不是平等的特殊用途实现。当然,这些实现不会是“领域的好公民”,因为它们无法与其他集合进行适当的比较。 (您会使用哪种 equals 方法?)然而,这并非没有先例。通过指定一个不“与等号一致”的比较器,可以创建一个违反 Map/Set 契约的 SortedMap/Set。

我将开放此 RFE 以跟踪对特殊用途、基于身份的 Set 和 Map 实现的支持。

最终评论(2011 年)指出,其中一个用例已通过

IdentityHashMap
等得到解决

如果你想浏览它们,有许多相关的问题。

© www.soinside.com 2019 - 2024. All rights reserved.