实习的目标是使equals
要实现的方法使用引用相等 as:
this eq that
(or this == that
在爪哇)。
很明显,该实现将具有最佳的运行时特性
越多传统的 equals
比较一些字段集。
仅当存在且仅有一个实例时,此比较才有效
每个“唯一对象”由对象的某些字段集确定。
Intern-ing 仅在以下情况下有效
的前期成本intern手术
可以通过(可能很多)调用的最小化成本来完全抵消equals
,
通过驱动HashMap
.
正如您所指出的,这intern-ing 可能需要一个潜在昂贵的缓存机制:
有运行时开销(执行检查)
和内存开销(缓存的大小)。
最直接的缓存方法是HashMap
,以及传统的equals
. hashCode
应该偷懒;缓存其结果,因此不需要重新计算。
可能需要考虑线程问题。
实现这种缓存的一种方法是使用trie http://en.wikipedia.org/wiki/Trie,也许在每个节点处用哈希表实现,并且其中每个“级别”对应于对象中的一个字段(第一级别 - 字段 1、第二级别、字段 2 等...),用于“用于的字段集”建立独特性。”
还有其他可行的方法来实现这种缓存。
请原谅我避免进一步讨论此类问题,
请允许我提出一些避免处理该问题的方法。
选项 1:不缓存
Claim: 您可能会获得足够有效的结果
使用快速哈希(并在内部缓存),
的“传统”实现equals
,
并从一个开始HashMap
or HashSet
of 足够的最小尺寸 https://stackoverflow.com/questions/1324064/performance-of-hashmap-with-different-initial-capacity-and-load-factor
理想情况下,哈希表中很少有冲突,
以及拨打电话的次数equals
是最小的。
选项 2:将多个字段映射到一个唯一字段String
[此方法假设“唯一定义对象的字段”是不可变的。如果情况并非如此,可以进行适当的调整来补偿。]
构建并缓存private unique: String
对应于唯一的对象实例。
例如,对于某些简单对象,以下内容可能是唯一的:
“用于建立唯一性的字段集”的字符串值的串联,以逗号分隔。
了解您的物体/场特征将有助于确定
如何创建这样一个独特的字符串。
有了这样的值,我们就可以避免单独的实习生/缓存机制
并通过实施两者保留大部分好处equals
and hashCode
就这一点而言unique
string:
def equals(thatObj: Any) = thatObj match {
case that : MyType => unique.equals(that.unique)
case _ => false
}
def hashCode() = unique.hashCode
选项 2 的替代方案:
[编辑:Rüdiger Klaehn 提供此链接提供了避免 String.intern() 的令人信服的证据 https://stackoverflow.com/questions/10624232/performance-penalty-of-string-intern]
Use String.intern
并调整equals
利用它:
private val unique = buildUnique().intern
def equals(thatObj: Any) = thatObj match {
case that : MyType => unique.eq(that.unique) // In Java: unique == that.unique
case _ => false
}