为什么java hashmap在计数为8时将bin树化,而在计数为6时将其取消?

为什么java hashmap在计数为8时将bin树化,而在计数为6时将其取消?,java,hashmap,Java,Hashmap,请开导我。我只能想象,这种情况可以避免频繁的树翻和不翻,而箱子的计数是8 /** * The bin count threshold for using a tree rather than list for a * bin. Bins are converted to trees when adding an element to a * bin with at least this many nodes. The value must be greater * than 2 and

请开导我。我只能想象,这种情况可以避免频繁的树翻和不翻,而箱子的计数是8

/**
 * The bin count threshold for using a tree rather than list for a
 * bin.  Bins are converted to trees when adding an element to a
 * bin with at least this many nodes. The value must be greater
 * than 2 and should be at least 8 to mesh with assumptions in
 * tree removal about conversion back to plain bins upon
 * shrinkage.
 */
static final int TREEIFY_THRESHOLD = 8;

/**
 * The bin count threshold for untreeifying a (split) bin during a
 * resize operation. Should be less than TREEIFY_THRESHOLD, and at
 * most 6 to mesh with shrinkage detection under removal.
 */
static final int UNTREEIFY_THRESHOLD = 6;

事实上,我是在问为什么这些值不一样。您能告诉我使用不同计数的具体原因吗?

Hashmap是hashtable数据结构的实现。当我们插入密钥、值对时,使用散列函数系统将识别密钥的散列值并插入到相应的bin中。如果插入另一个键,则第二个键的值对和散列值也会提供相同的值,它将进入同一个bin。这种情况称为哈希冲突。如果bin的大小很小,那么在以后搜索元素时,bin的列表/数组实现可以提供更好的性能。否则,二进制树可能有助于轻松识别密钥。您注意到的是hashmap的性能优化。

一个“好的哈希表”将包含对象,这些对象的类定义了一个产生好的分布的哈希函数。一个好的哈希表将有适当数量的容器,这样哈希冲突就不会频繁发生。上面的常量描述了哈希表在发生足够的哈希冲突时的性能特征,从而导致垃圾箱开始变得“太满”。当箱子中的物品数量较少时,线性搜索是最有效的搜索策略。当bin中的项目数量很大时,树是最有效的。您是在问为什么使用这些特定阈值,还是为什么值不相同?我假设它们不同,否则它将允许在相同的计数下进行树化和取消树化(这将是有问题的),差异是2而不是1,以防止在移除项目并随后读取(反之亦然)时,地图花费太多时间在两种模式之间切换。但是,您的问题需要熟悉Java的
HashMap
实现和实际的设计决策。除了像我这样的猜测之外,你不可能在这里得到真正的答案。这使你的问题偏离了主题,因为它主要会产生意见。@AndyTurner通常,我会问为什么值不一样。你能告诉我关于它们使用不同计数的原因的具体统计信息吗?“事实上,我是在问为什么这些值不一样。你能告诉我关于它们使用不同计数的原因的具体静态数据吗?”?" ... 这个问题可能没有分析性的答案。Java集合框架现在已经非常陈旧了。随着平台的每次迭代,HashMap实现都得到了调整、优化和稳步改进。在Java8中(我认为)最新的实现被删除了,这为一些系统带来了可衡量的性能改进。您看到的阈值可能是仔细调整的结果,仅此而已。