标签:key值 时间 tree 初始 ring 一个 rev ash 函数
JDK8中
JDK8中的hashMap实现采用位桶+链表+红黑树方式,当链表的长度超过阈值(默认阈值为8),链表将转为红黑树,这样设计将减少查找的时间。
在JDK1.6,JDK1.7中
HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
hashMap实现原理(步骤)
首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,这样大大提高了查找的效率。
当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中。
hashMap数据结构
1、使用位桶数组
transient Node<k,v>[] table;//存储(位桶)的数组</k,v>
2,数组元素Node<K,V>实现了Entry接口
//node是单向链表,它实现了Map.Entry接口
static class Node<k,v> implements Map.Entry<k,v>{
final int hash;
final K key;
V value;
Node<k,v> next;
//构造函数hash值 键 值 下一个节点
Node(){
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey(){
return key;
}
public final K getValue(){
return value;
}
public final String toString(){
return key+ "=" +value;
}
public fianl int hashCode(){
retrun Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue){
V oldValue = value;
value = newValue;
return oldValue;
}
//判断两个node是否相等,若key和value都相等返回true,否则false,与自己比较为true
public final boolean equals(Object o){
if(o == this)
return true;
if(o instanceof Map.Entry){
Map.Entry<!--?,?--> e = (Map.Entry<!--?,?-->)o;
if(Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue()))
return true;
}
return false;
}
3,红黑树
//红黑树
static final class TreeNode<k,v> extends LinkedHashMap.Entry<k,v>{
TreeNode<k,v> parent; //父节点
TreeNode<k,v> left; //左子树
TreeNode<k,v> right; //右子树
TreeNode<k,v> prev; //needed to unlink next upon deletion
boolean red; //颜色属性
TreeNode(int hash, K key,V value, Node<k,v> next){
super(hash, key, val, next );
}
//返回当前节点的根节点
final TreeNode<k,v> root(){
for(TreeNode<k,v> r = this, p;;){
if((p = r.parent) == null)
return r;
r = p;
}
}
}
标签:key值 时间 tree 初始 ring 一个 rev ash 函数
原文地址:https://blog.51cto.com/11585002/2494724