【问题标题】:Java: Need a hash Map where one supplies a function to do the hashingJava:需要一个哈希映射,其中提供一个函数来进行哈希
【发布时间】:2011-03-27 23:31:27
【问题描述】:

我想知道一个像常规 HashMap/Hashtable 一样工作的 Map,除了它需要一个返回哈希码并执行相等测试的函数,而不是让 HashMap 使用 Object.hashCode/equals。

我不能使用 TreeMap 因为对象没有实现 Comparable 并且没有稳定的方法来处理不相等对象的情况。不能使用 System.identityHashCode,因为不相等的对象可能会发生冲突。

理想情况下,如果 Map 以类似的方式采用一个函数,可以为 TreeMap 提供自定义 Comparator 而不是让 TreeMap 将参数转换为 Comparable,那将是很棒的。

解决此问题的唯一方法是包装每个密钥并让包装器执行自定义散列/等于,但肯定有更好的方法。

【问题讨论】:

  • “不能使用 System.identityHashCode,因为不相等的对象可能会发生冲突。”这几乎是哈希表的一部分。哈希冲突确实发生在每个哈希表实现中。
  • 对象都是同一类型吗?让他们实施 Comparable 是否有障碍?我想可以通过子类化 HashMap 和覆盖函数并传入对它们的函数引用来设置解决方案。但它似乎比实现 Comparable 要付出更多的努力。
  • 这是一个多用途的 q,不幸的是,很多时候类不是你的,你不能改变它们,因此需要提供一个自定义函数来处理散列/相等测试。
  • @biziclop,是的,当然会发生哈希冲突,但我希望该函数也能处理相等性测试,这样我的函数就可以说明在计算哈希和相等性时什么是重要的。
  • 只是想让你知道我有完全相同的问题。我目前正在使用具有自己的 equals() 和 hashCode() 方法的包装器对象,并且包装器占用了数百兆字节的堆内存。我打算采用 HashMap 的开源实现并对其进行调整。

标签: java


【解决方案1】:

您是否考虑过对要缓存的对象使用简单的包装器?

class Wrapper {
   YourObject object;

   public boolean equals(Object someOther) {
   ...
   }
   public int hashCode() {
   }
}

【讨论】:

  • 他说他在他的原始帖子中做过(您可能想重新阅读它),但我同意这可能是最好的解决方案,不应该这么快就被丢弃。
  • 您可以将此解决方案更进一步,编写一个简单的 Map 包装器,而不是在内部使用此哈希包装器。地图包装器可以在添加或检索对象时处理对象的包装和向上包装。
  • @jt 问题是还需要处理 keySet、entrySet 它们的迭代器等,这并不难,但确实需要一些工作......
  • 这个问题是需要额外的内存量和构建新实例所需的额外性能。每次从地图中检索值时,也会进行实例构造。您不能只使用 equals 与未包装的键进行比较,因为您不知道包装的映射如何处理比较 - 它总是将包含的键与查询的键进行比较,还是反过来比较它们.
【解决方案2】:

正如其他答案所建议的那样,使用具有所需 hashCode 和 equals 的对象包装您的对象通常是最好的方法。如果在极少数情况下,您希望函数在 Object 上使用原始的 equals 和 hashCode 实现,那么该用例实际上是 IdentityHashMap 。但是,我很欣赏您想要的功能可能不止于此。

【讨论】:

    【解决方案3】:

    使用TreeMap时,地图中的对象不需要实现Comparable。

    【讨论】:

    • 你误解了如果我使用 TreeMap 会发生的问题。如果我提供自己的自定义比较器,我该如何比较不相等的对象?我不能使用 System.identityHashcode,因为当存在不相等对象的哈希码冲突时会出现另一个问题!
    • 您将实现 Comparator 的 compare() 方法,以根据可用的公共方法和/或键类的字段一致地对键进行排序。
    • 或者只是将哈希码作为一个 int 进行比较 :)。太糟糕了,没有 IEqualityComparer
    【解决方案4】:

    Plume-lib 的WeakHasherMap 做你想做的事:它的构造函数将Hasher 对象作为参数,该对象定义了一个hashCode() 方法和一个equals() 方法。

    (这在你写问题的时候就已经存在,但我现在才注意到你的问题,在你问这个问题 6.5 年后。)

    编辑:我是 plume-lib 的维护者。

    【讨论】:

      【解决方案5】:

      I proposed an interface for such a "hash function" some time ago.

      现在您需要采用哈希映射的任何实现(例如,OpenJDK 的一个是 GPL),并使用对该哈希对象的调用修改所有对 hashCode().equals() 的调用。我做过一次(很多年前),但没有发表。

      【讨论】:

        猜你喜欢
        • 2013-11-23
        • 2018-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-05
        • 2011-08-06
        • 1970-01-01
        • 2019-04-29
        相关资源
        最近更新 更多