【问题标题】:Tree-bins : using identityHashCode to order non-Comparables makes the effort useless?Tree-bins:使用 identityHashCode 来订购 non-Comparables 使努力毫无用处?
【发布时间】:2020-04-16 08:55:35
【问题描述】:

几乎是IdentityHashCode in HashMap's bucket 的扩展:

我了解 Java 8 HashMap 实现中的树箱被吹捧为将查找的最坏情况复杂性降低到 O(lg(n)) 而不是 O(n) ,例如对于大型垃圾箱。但是对于非 Comparable 类,它们使用identityHashCode 进行排序插入。因此,当finding 时,我们需要在两个子树中查找。

现在查看两个子树会立即转换最坏情况的复杂度:O(n) 而不是 O(lg(n))。所以所有转换成树的辛勤工作,然后在UNTREEIFY_THRESHOLD 上取消树化都是浪费的,我们没有任何优势?

我错过了什么?

【问题讨论】:

    标签: java java-8 tree hashmap


    【解决方案1】:

    对于非 Comparable,bin 后面的树利用更快的查找具有 不同 hashCode() 值且映射到同一 bin 的对象。

    对于具有相同 hashCode() 值的对象,没有什么可以做的,因为没有区别特征。系统必须对所有具有相同hashCode() 值的键进行全面搜索。

    正如链接的问题所说,identityHashCodes 仅在插入期间用作决胜局。它不能在查找期间使用,因为使用具有相同内容的 不同 对象(即不同的 identityHashCodes)进行查找,必须找到由 hashCode()equals() 定义的匹配项。

    【讨论】:

    • 当对象映射到同一个 bin 并且满足其他先决条件时,HashMap 始终使用二叉树而不是哈希码(首先)。仅对于具有相同哈希码的对象,如果它们是Comparable,它会使用它们的compareTo 方法。但底线保持不变,只有当对象具有相同的哈希码且不可比较或compareTo 返回零但equals 返回false 并且它们具有相同的类名时,才使用身份哈希码.
    • @Jeeves 您认为应用程序可能从外部源接收哪种数据类型,这是不可比较的,但具有公开记录的哈希码实现?
    • @Jeeves 因为您声称存在这种类型,甚至具有如此大的相关性,以至于有人会在“大型碰撞数据库”中收集该类型的实例来攻击系统。这将要求该系统使用这种数据类型并接受它的实例作为外部输入。
    • @Jeeves 实际上,我对您要争论的内容感到完全困惑。您建议从HashMap 中删除改进,使其性能特征恶化,并创建另一个名为TreeBinnedHashMap 的类,其工作方式与当前的HashMap 完全相同。为什么?您认为通过使HashMap less 高效能获得什么? --- 我相信你提到TreeBinnedHashMap 应该强制元素必须是Comparable,但由于没有什么会强迫人们使用该类而不是HashMap,你认为你这样做已经完成了什么?
    • @Jeeves 很有趣,您如此专注于 最小的 障碍。大多数服务器使用开源软件框架构建,这些框架允许从公共来源获取其类型的哈希码算法。您只需要在这些来源中找到一个无法实现可比较的实际类型,用作大型哈希映射的键接受外部来源的输入,以证明您的假设场景值得浪费如此多的时间。哦,别忘了解释为什么 Java 8 的改进使情况比之前的二十年更糟。
    猜你喜欢
    • 1970-01-01
    • 2020-06-06
    • 2022-01-05
    • 1970-01-01
    • 2021-05-01
    • 2015-02-16
    • 2020-11-30
    • 2021-01-05
    • 2021-02-19
    相关资源
    最近更新 更多