当前位置: 首页 > 知识库问答 >
问题:

Java 8 Hashmap内部

禄光霁
2023-03-14

我已经完成了Java8 Hashmap的实现,并带着以下疑问来到这里。请帮我澄清一下:

  1. 我在一篇文章中读到,具有相同哈希代码的节点将被添加到与链表相同的bucket中。它说,这个链表的新节点将被添加到head而不是tail中,以避免尾部遍历。但当我看到源代码时,新的节点被添加到尾部。对吗
  2. 我没有完全理解这个变量的最小树容量。是不是经过这么多的计算,整个地图会被转换成树(从数组到树)

共有2个答案

鱼意远
2023-03-14

Peter Lawrey关于MIN_TREEIFY_容量的回应是错误的。

此常量默认为64,并在java.util.HashMap#treeifyBin方法中使用,如果存储桶的大小大于8(TREEIFY_THRESHOLD),则调用该方法。

在java.util.HashMap#treeifyBin方法中,如果哈希表大小小于64,则整个表是RESIZED-加倍的,否则,问题所在的桶是TREEIFIED-桶的DS-链表转换为二叉树。

关键是保持O(1)插入或查找——如果哈希表大小很小(64),我们可以通过加倍来轻松调整它的大小,因此存储桶的范围将加倍,哈希键的冲突将更少,每个存储桶的项目将更少。

如果表大小大于64,那么将哈希表大小加倍可能会很昂贵,最好将当前存储桶的链表转换为二叉树存储桶,这样搜索速度更快(链表搜索为O(n),而二元树状搜寻为O(log(n))。

韩嘉祯
2023-03-14

但当我看到源代码时,新的节点被添加到尾部。对吗?

在旧版本中,它被添加到头部。然而,Java8中做了许多更改,而Java8确实做到了这一点。

class A {
    static class SameHash {
        final int n;

        SameHash(int n) {
            this.n = n;
        }

        @Override
        public int hashCode() {
            return 1;
        }

        @Override
        public String toString() {
            return "SameHash{" +
                    "n=" + n +
                    '}';
        }
    }

    public static void main(String[] args) {
        HashSet<SameHash> set = new HashSet<>();
        for (int i = 1; i <= 4; i++)
            set.add(new SameHash(i));
        System.out.println(set);
    }
}

印刷品

[SameHash{n=1}, SameHash{n=2}, SameHash{n=3}, SameHash{n=4}]

注意:密钥可以有不同的哈希代码,但可以在同一个存储桶中结束。

我没有完全理解这个变量MIN_TREEIFY_CAPACITY。是不是就像经过这么多计数后,整个地图将被转换为树(从数组到树)?

在此计数之后,如果密钥是可比较的,则桶将转换为树

 类似资料:
  • 问题内容: 我想了解当CSS是CSS元素的DOM子元素(因此block元素是inline元素的子元素)时会发生什么情况。 CSS 2.1规范的“ 匿名块框”部分描述了这种情况:该示例包括以下规则… …以及随附的文字说… BODY元素包含一个匿名文本块(C1),然后是一个块级元素,然后是另一个匿名文本块(C2)。结果框将是围绕BODY的匿名阻止框,其中包含C1周围的匿名阻止框,P阻止框和C2周围包含

  • 实施可重用组件的各种工具。 函数 d3.functor(value) 如果参数value 是个函数,返回这个函数。否则,返回一个能够输出这个参数的函数变量。该方法用来将常量参数升级转换成函数,以备需要指定属性为常量或者函数的时候,直接实现。比如:许多D3 layouts需要指定属性成这种格式,当我们自动转换值到函数的时候,这样可以简化实现。 d3.rebind(target, source, na

  • 我最近需要在一个JScrollPane的viewport视图中放置几个组件,其中包括一个JTextPane。 我将所有组件(两个JPanel和JTextPane)放在另一个JPanel中,这个JPanel有一个BorderLayout LayoutManager,并将该JPanel设置为ScrollPane的viewport视图。 我立即注意到: JTextPane不再根据JScrollPane的

  • 问题内容: VS 哪种被认为是 正确的 (语法上)且性能最高的方法,为什么? 后一个示例中的语法对我来说似乎更合乎逻辑,但我的假设是JOIN会更快。 我看过查询计划,还无法从中解密任何内容。 查询计划1 查询计划2 问题答案: 两种语法有不同的用途。假设使用Join语法,则需要StockToCategory和Category表中的某些内容。如果每个类别的StockToCategory表中有多个条目

  • 在本章中,我们将讨论使用Socket.IO,事件和消息进行回退,连接。 Fallbacks Socket.IO有很多底层传输机制,它处理由于跨浏览器问题,WebSocket实现,防火墙,端口阻塞等引起的各种约束。 尽管W3C已经为WebSocket API定义了规范,但它仍然缺乏实现。 Socket.IO为我们提供了回退机制,可以处理这些问题。 如果我们使用本机API开发应用程序,我们必须自己实现

  • 问题内容: 请看下面的代码: 在上面的代码中,在方法ModifyList()中声明的匿名内部类的实例能够访问传递给该方法的参数。AFAIK Java为内部类创建一个单独的字节码文件。 谁能解释一下Java在字节码级别上如何处理这些局部变量绑定?我的意思是,Java如何精确跟踪对作为参数传递给该方法的对象的引用? 任何帮助将不胜感激! [抱歉我的英语不好! 如果您理解我的问题,请编辑这篇文章,并删除

  • 我有一个xml布局,它有以下视图:滚动视图->Relationvelayout->Some views+Tablayout+ViewPager->RecylerView(在ViewPager的片段中)。ViewPager有一些固定的高度(保持它“wrap_content”根本不会显示它)。现在的问题是Recylerview永远不会滚动。我已经尝试了几个已经发布的解决方案,比如在“嵌套滚动视图”中包

  • 我试图运行一个简单的mapdb示例,但出现了以下错误: 我的班级: 我的pomx.xml 我跑得很快-