Java8HashMapBucket中使用了哪种树类型?
正如我在java8中所知道的,HashMap的bucket实现发生了一些变化。如果bucket size超过某个值,则列表将转换为“平衡树” 我不明白Java8HashMapBucket中使用了哪种树类型?,java,hashmap,java-8,Java,Hashmap,Java 8,正如我在java8中所知道的,HashMap的bucket实现发生了一些变化。如果bucket size超过某个值,则列表将转换为“平衡树” 我不明白 1.Oracle JDK中使用了哪种类型的平衡树?(AVL?红黑?类似于数据库中的索引?) 2.是二叉树吗? 3.据我所知,排序是根据hashcode执行的。例如,在我的桶中,我有102个元素。100个值与hashcode的值相等12(我知道它值得,但我只需要了解这种行为),2个值与hashcode的值相等22。 如何对值执行搜索 看看实现,它看
1.Oracle JDK中使用了哪种类型的平衡树?(AVL?红黑?类似于数据库中的索引?)
2.是二叉树吗?
3.据我所知,排序是根据hashcode执行的。例如,在我的桶中,我有102个元素。100个值与hashcode的值相等12(我知道它值得,但我只需要了解这种行为),2个值与hashcode的值相等22。
如何对值执行搜索
看看实现,它看起来像一个二叉树。更具体地说,下面的评论表明这是一棵红黑相间的树:
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // red-black tree links
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
...
}
如您所见,这类似于标准的二进制搜索树搜索。首先,他们搜索一个
TreeNode
,该TreeNode与搜索的键具有相同的hashCode
(因为HashMap
的单个bucket可能包含具有不同hashCode
的条目)。然后继续执行,直到找到一个键等于所需键的TreeNode
。如果键的类实现了Comparable
,则二次搜索使用compareTo
。否则,将执行更详尽的搜索。但是如果未实现compareTo?如果JDK已经有TreeMap,那么用另一个名称创建同一个类的原因是什么?@gstackoverflow它不是同一个类。HashMap中使用的TreeNode
是一个实现细节。当单个容器中的条目数超过某个阈值时,它应该比HashMap的单个容器的原始链表实现提供更好的性能。我的问题有点不同。为什么jdk创始人不能在HashMap中使用TreeMap而不是TreNode?@gstackoverflow您可以自己查看代码。有一个find(inth,objectk,Class kc)
方法,它查找具有传递的hashCode(h)且其键等于k的树节点。如果它到达一个树节点,其哈希代码为所需值,但键不相等,则它要么使用compareTo(如果可用),要么在右子树中递归搜索键,如果未找到,则在左子树中搜索键。请注意,您不应依赖此行为。如果代码已经有了错误的行为(集群哈希代码),这是一种特定于实现的回退。如果您的键散列不好,但具有可比性,您也可以从一开始就使用树映射。
/**
* Finds the node starting at root p with the given hash and key.
* The kc argument caches comparableClassFor(key) upon first use
* comparing keys.
*/
final TreeNode<K,V> find(int h, Object k, Class<?> kc) {
TreeNode<K,V> p = this;
do {
int ph, dir; K pk;
TreeNode<K,V> pl = p.left, pr = p.right, q;
if ((ph = p.hash) > h)
p = pl;
else if (ph < h)
p = pr;
else if ((pk = p.key) == k || (k != null && k.equals(pk)))
return p;
else if (pl == null)
p = pr;
else if (pr == null)
p = pl;
else if ((kc != null ||
(kc = comparableClassFor(k)) != null) &&
(dir = compareComparables(kc, k, pk)) != 0)
p = (dir < 0) ? pl : pr;
else if ((q = pr.find(h, k, kc)) != null)
return q;
else
p = pl;
} while (p != null);
return null;
}