覆盖哈希函数

Ruby 哈希使用方法 hasheql? 来执行哈希操作,并将存储在哈希中的对象分配给内部哈希箱。Ruby 中 hash 的默认实现是哈希对象的所有成员字段上的 杂音哈希函数 。要覆盖此行为,可以覆盖 hasheql? 方法。

与其他哈希实现一样,如果 a.hash == b.hash 将两个对象 a 和 b 散列到同一个桶中,如果 a.eql?(b) 将被视为相同。因此,当重新实现 hasheql? 时,应该注意确保如果 abeql? 下相等,则它们必须返回相同的 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