【问题标题】:How does Set ensure equatability in Swift?Set 如何确保 Swift 中的等价性?
【发布时间】:2017-12-06 15:00:51
【问题描述】:

我正在阅读Set

当您需要有效地测试成员资格并且您不关心集合中元素的顺序时,或者当您需要确保每个元素在集合中只出现一次时,您可以使用集合而不是数组.

基本上Set保证唯一性,它有一些方法,依赖Hashable

使用 contains(_:) 方法测试集合是否包含特定元素。

使用减法(_:) 方法创建一个新集合,其中包含一个集合中不在另一个集合或序列中的元素

但是 2 个不同的对象可以有相同的hashValue,就像这篇文章中的Swift Hashable

不要假设具有相同哈希值的类型的两个实例是相等的。根据我们计算哈希值的方式,我们可能会遇到两个不同实例共享相同哈希值的冲突。 Hashable 协议只需要反过来——两个相等的实例具有相同的哈希值。

那么如果2个对象有相同的hashValue,而Set只保存了1个,那我们就有问题了?

【问题讨论】:

  • 文档无处说明只保存具​​有不同 hashValue 的项目。
  • "那么如果2个对象有相同的hashValue,而Set只保存了1,那么我们有问题吗?"不,Set 将存储 2 个对象。这种情况称为哈希冲突,Set 会处理这种情况。

标签: swift set hashable


【解决方案1】:

符合Hashable 的对象也必须是EquatableSet 使用== 来测试是否相等,它不仅仅依赖于hashValue

来自 Apple 在Hashable 上的文档:

符合 Hashable 协议

在 设置或作为字典的键类型,将 Hashable 一致性添加到 您的类型通过提供 hashValue 属性。可哈希协议 继承自 Equatable 协议,因此您还必须添加一个等于 自定义类型的运算符 (==) 函数。

文档接着说:

集合和字典的性能取决于最小化的哈希值 分别为其关联的元素和键类型发生冲突。

所以,hashValue 只是用于唯一性的第一个测试;如果hashValues 匹配,那么Set 将使用计算量更大的== 来测试唯一性。

【讨论】:

    猜你喜欢
    • 2020-12-16
    • 2015-05-15
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多