覆盖哈希函数
Ruby 哈希使用方法 hash
和 eql?
来执行哈希操作,并将存储在哈希中的对象分配给内部哈希箱。Ruby 中 hash
的默认实现是哈希对象的所有成员字段上的 杂音哈希函数 。要覆盖此行为,可以覆盖 hash
和 eql?
方法。
与其他哈希实现一样,如果 a.hash == b.hash
将两个对象 a 和 b 散列到同一个桶中,如果 a.eql?(b)
将被视为相同。因此,当重新实现 hash
和 eql?
时,应该注意确保如果 a
和 b
在 eql?
下相等,则它们必须返回相同的 hash
值。否则,这可能会导致散列中出现重复条目。相反,hash
实现中的不良选择可能会导致许多对象共享相同的哈希桶,从而有效地破坏 O(1)
查找时间并导致 O(n)
在所有对象上调用 eql?
。
在下面的示例中,只有类 A
的实例存储为键,因为它首先添加:
class A
def initialize(hash_value)
@hash_value = hash_value
end
def hash
@hash_value # Return the value given externally
end
def eql?(b)
self.hash == b.hash
end
end
class B < A
end
a = A.new(1)
b = B.new(1)
h = {}
h[a] = 1
h[b] = 2
raise "error" unless h.size == 1
raise "error" unless h.include? b
raise "error" unless h.include? a