Hash
通过高效的哈希来优化相等性检查,从而在哈希集合、哈希映射等集合中实现更快的比较。
Hash 接口与 Equal 接口密切相关,它通过提供一种哈希机制,在优化相等性检查方面扮演辅助角色。哈希是高效判断两个值是否相等的重要步骤,尤其是在与哈希表这类数据结构配合使用时。
Hash 在相等性检查中的角色
Hash 接口的主要目的是提供一种快速且高效的方式,用来判断两个值是否一定不相等,从而对 Equal 接口形成补充。当两个值都实现了 Equal 接口时,会先比较它们的哈希值(通过 Hash 接口计算得出):
- 哈希值不同:如果哈希值不同,那么可以确定这两个值本身也不同。这一快速检查使系统能够避免一次可能开销很大的相等性比较。
- 哈希值相同:如果哈希值相同,并不能保证这两个值相等,只能说它们可能相等。在这种情况下,会使用 Equal 接口执行一次更彻底的比较,以确定它们是否真正相等。
这种方式极大地加快了相等性检查的过程,尤其是在那些快速查找和插入至关重要的集合中,例如哈希集合(hash set)或哈希映射(hash map)。
实现 Hash 接口
设想这样一个场景:你有一个自定义的 Person 类,并且希望根据属性判断两个实例是否相等。
通过同时实现 Equal 和 Hash 接口,你可以高效地管理这些检查:
示例(为自定义类实现 Equal 和 Hash)
import { Equal, Hash } from "effect"
class Person implements Equal.Equal {
constructor(
readonly id: number, // Unique identifier
readonly name: string,
readonly age: number,
) {}
// Define equality based on id, name, and age
[Equal.symbol](that: Equal.Equal): boolean {
if (that instanceof Person) {
return (
Equal.equals(this.id, that.id) &&
Equal.equals(this.name, that.name) &&
Equal.equals(this.age, that.age)
)
}
return false
}
// Generate a hash code based on the unique id
[Hash.symbol](): number {
return Hash.hash(this.id)
}
}
const alice = new Person(1, "Alice", 30)
console.log(Equal.equals(alice, new Person(1, "Alice", 30)))
// Output: true
const bob = new Person(2, "Bob", 40)
console.log(Equal.equals(alice, bob))
// Output: false
说明:
[Equal.symbol]方法通过比较Person实例的id、name和age字段来判断相等性。这种方式确保相等性检查是全面的,会考虑所有相关属性。[Hash.symbol]方法使用这个 person 的id计算哈希码。该值用于在哈希操作中快速区分不同实例,从而优化那些使用哈希的数据结构的性能。- 当把
alice与一个属性值完全相同的新Person对象比较时,相等性检查返回true;而把alice与bob比较时,由于它们的属性值不同,返回false。