- HashMap底层数据结构
- JDK7 :数组 + 链表
- JDK8 : 数组 + 链表 + 红黑树
当链表中的元素个数⼤于8之后,还会判断⼀下当前数组的⻓度,如果数组⻓度⼩于64时,此时并不会转化为红⿊树,⽽是进⾏扩容。 只有当链表中的元素个数⼤于8,并且数组的⻓度⼤于等于64时才会将链表转为红⿊树。 - JDK7中HashMap的put方法实现过程:
1.根据key算出hashcode 取模,得到数组下标位置
2.判断数组下标位置是否为空
3.为空则没有冲突,直接用数组存储
4.不为空则发生哈希冲突,用链表存储
5.返回value - JDK7中HashMap的get方法实现过程
1.根据key算出数组下标
2.数组查询
3.判断key和entry是否相等,相等则返回
4.不相等则判断next是否为空,不为空则判断key和entry是否相等
5.直到相等或为null 为止
- 代码实现
- 首先定义一个Map接口(里面还定义了一个内部Entry接口)
public interface Map<K,V> {
V put(K k,V v);
V get(K k);
int size();
interface Entry<K,V> {
K getKey();
V getValue();
}
}
- 定义一个HashMap类实现Map接口(内部类Entry继承实现Entry接口)
public class HashMap<K,V> implements Map<K,V> {
Entry<K,V>[] table = null;
int size = 0;
public HashMap() {
table = new Entry[16];
}
@Override
public V put(K k, V v) {
int index = hash(k);
Entry<K,V> entry = table[index];
if (null == entry) {
table[index] = new Entry<>(k,v,index,null);
size++;
}else {
table[index] = new Entry<>(k,v,index,entry);
}
return table[index].getValue();
}
public int hash(K k) {
int a = k.hashCode()%15;
return a > 0 ? a : -a;
}
@Override
public V get(K k) {
int index = hash(k);
if (0 == size){
return null;
}
Entry<K,V> entry = findValue(table[index],k);
return entry == null ? null : entry.getValue();
}
private Entry<K,V> findValue(Entry<K,V> entry, K k) {
if (k.equals(entry.getKey()) || k == entry.getKey()){
return entry;
}else {
if(null != entry.next){
return findValue(entry.next,k);
}
}
return null;
}
@Override
public int size() {
return size;
}
class Entry<K,V> implements Map.Entry<K,V> {
K k;
V v;
int hash;
Entry<K,V> next;
public Entry(K k,V v,int hash,Entry<K,V> next){
this.k = k;
this.v = v;
this.hash = hash;
this.next = next;
}
@Override
public K getKey() {
return k;
}
@Override
public V getValue() {
return v;
}
}
}
public class Test {
public static void main(String[] args) {
Map<Object,Object> map = new HashMap<>();
map.put("yzh","纵有疾风起");
map.put("kk","人生不言弃");
System.out.println(map.get("yzh"));
System.out.println(map.get("kk"));
}
}
- 效果
