Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8哈希映射内部_Java_Hashmap - Fatal编程技术网

Java8哈希映射内部

Java8哈希映射内部,java,hashmap,Java,Hashmap,我已经完成了Java8HashMap的实现,并带着以下疑问来到这里。请帮我澄清一下: 我在一篇文章中读到,使用相同哈希代码的节点 将添加到与链表相同的存储桶中。它说新的 此链表的节点将添加到head而不是tail中,以避免尾部遍历。 但当我看到源代码时,新的节点被添加到尾部。 对吗 我没有完全理解这个变量的最小树容量。经过这么多的计算后,整个映射是否会转换为树(从数组到树) 但当我看到源代码时,新的节点被添加到尾部。对吗 在旧版本中,它被添加到头部。然而,Java8中做了许多更改,而Java8没

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

  • 我在一篇文章中读到,使用相同哈希代码的节点 将添加到与链表相同的存储桶中。它说新的 此链表的节点将添加到head而不是tail中,以避免尾部遍历。 但当我看到源代码时,新的节点被添加到尾部。 对吗
  • 我没有完全理解这个变量的最小树容量。经过这么多的计算后,整个映射是否会转换为树(从数组到树)
  • 但当我看到源代码时,新的节点被添加到尾部。对吗

    在旧版本中,它被添加到头部。然而,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);
        }
    }
    
    注意:键可以有不同的hashcode,但可以在同一个bucket中结束

    我没有完全理解这个变量的最小树容量。经过这么多的计算后,整个映射是否会转换为树(从数组到树)


    在此计数之后,如果密钥是可比较的,则桶将转换为树。Peter Lawrey关于最小树容量的响应是错误的

    该常量默认为64,并在java.util.HashMap#treeifyBin方法中使用,该方法在bucket的大小大于8(TREEIFY#u阈值)时调用

    在java.util.HashMap#treeifyBin方法中,如果哈希表大小小于64,则整个表的大小将调整一倍,否则,所讨论的bucket将被树化—bucket的DS链表将转换为二叉树

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


    如果表的大小大于64,那么将哈希表的大小增加一倍的代价可能会更高,最好将当前bucket的链表转换为二叉树bucket,二叉树bucket的搜索速度更快(链表搜索为O(n),而二叉树搜索为O(log(n)).

    因此,在表大小达到64且bucket大小达到8后,该bucket将单独转换为tree right?或表中的所有bucket?正确,只有达到阈值的bucket将从节点(链表)转换为TreeNode(平衡/二叉树)。请记住,也有从树节点到节点的反向转换,当哈希表调整大小时,以及当一些大存储桶的大小小于untreefy_THRESHOLD=6时,就会发生这种情况
    [SameHash{n=1}, SameHash{n=2}, SameHash{n=3}, SameHash{n=4}]