【问题标题】:Why can we supply a Comparator to TreeSet but not something like Hasher to HashSet?为什么我们可以为 TreeSet 提供 Comparator 而不能为 HashSet 提供类似 Hasher 的东西?
【发布时间】:2011-05-25 08:01:34
【问题描述】:

在 Java 6 中,我的理解是,您可以在创建 TreeSet 时为其提供 Comparator 以覆盖集合中对象的“自然顺序”。

您是否有任何想法,为什么 Java 不支持提供覆盖集合中对象的“自然散列”的“Hasher”?

编辑: 在未来设计 API 时,从您那里获得意见可能会对我有所帮助。

谢谢。

【问题讨论】:

  • API 就是这样。问“为什么”只能是猜测。
  • 你可以对 Set 和 equals 提出同样的问题。

标签: java hashset treeset


【解决方案1】:

【讨论】:

  • 好东西!下次我在问问题之前必须查阅 Sun 的错误数据库。
【解决方案2】:

Hasher 对象对于Object 类中的hashCode() 方法是多余的。

如果您想影响散列的性质,您应该覆盖在Object 上定义的hashCode() 方法。请务必同时覆盖equals(Object),因为这两者应该始终一起使用。

HashSet 或其他类似的数据结构将使用对象hashCode() 方法获取哈希值以确定 bin 存储。然后它将使用 equals() 将该对象与同一 bin 中的其他对象进行比较以确定相等性。

生成的哈希码对于该特定类别的对象必须是唯一的。这可以简单地通过覆盖hashCode() 方法来确保,并且不需要在实现之间进行更改。 Hasher 对象只会混淆并且没有其他用途。我想不出一个用例需要多个哈希码来存储在不同的数据结构中。

【讨论】:

  • 绝对正确,您对为什么有比较器而不是哈希器的输入是?
  • Object 上的hashCode() 方法已经完成时,您不需要Hasher。如果Object 上有一个compareTo() 方法,那么你就不需要Comparator
  • 如果你想覆盖自然顺序,你确实需要一个比较器,但我知道你来自哪里。谢谢!
【解决方案3】:

以下是几个可能的原因:

  • 简单性 - 大多数人不需要多个哈希函数,因此为了保持 API 简单,依赖单个 Object.hashCode() 方法是有意义的

  • 性能 - 至少在标准库中, HashSets 和 HashMaps 等需要 非常优化,因为它们 如此广泛使用。这没有意义 有调用 a 的开销 单独的“哈希器”,无论多么小 开销可能是。

  • 私人领域 - 存在的问题是 hashCode() 可能依赖于私有 领域,可能很难 为某些人创建外部“哈希” 对象。

【讨论】:

    【解决方案4】:

    确实如此!查看Object.hashCode 方法。

    再次阅读您的问题后,我可能已经过火了。我现在看到您说“覆盖”自然哈希。通常我们会在对象级别覆盖哈希值并放弃使用覆盖哈希器。

    哈希意味着比比较器更通用。也就是说,散列应该几乎总是创建统一的不信任值,几乎没有冲突的机会。使用它们的容器应该很少需要专门的哈希器。

    【讨论】:

    • 你回来回答问题了!为此 +1 :)
    【解决方案5】:

    您可以通过包装一个对象来更改对象的哈希码,该对象以您的方式实现哈希码。假设您可能希望一个对象以多种方式排序,但没有多个散列策略。

    参考Trove4j 支持其 HashMap 的散列策略,虽然我经常使用这个库,但我只使用过自定义散列策略。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2016-01-29
      • 2013-07-16
      • 2012-11-04
      相关资源
      最近更新 更多