map集合中有一个实现类是hashMap
JDK1.7中
hashMap是数组加链表形式存在的
首先我们要定义一个Map接口
接口中我们定义一个get,put,size,和一个存数据的内部类
public interface Map<K,V> {
public V get(K k);
public V put(K k,V v);
public int size();
interface Entry<K,V>{
public K getKey();
public V getValue();
}
}
接下来就是实现这接口
public class HashMap<K,V> implements Map<K,V>{
int size = 0;
Entry<K,V> table[] = null;
public HashMap(){
table = new Entry[16] ;
}
public V get(K k) {
int index = hast(k);
Entry<K, V> entry = table[index];
if(entry == null || size == 0){
return null;
}
return find(k,entry);
}
private V find(K k, Entry<K, V> entry) {
if(k==entry.getValue()|| k.equals(entry.getKey())){
return entry.getValue();
}else{
return find(k, entry);
}
}
public V put(K k, V v) {
int index = hast(k);
Entry<K, V> entry = table[index];
if(entry==null){
table[index] = new Entry<K,V>(k,v,null,index);
size++;
}else{
table[index] = new Entry<K,V>(k,v,entry,index);
size++;
}
return table[index].getValue();
}
private int hast(K k) {
int index = k.hashCode()%16;
return index >0?index:-index;
}
public int size() {
return size;
}
class Entry<K,V> implements Map.Entry<K, V>{
K k;
V v;
Entry<K,V> next;
int hast;
public Entry(K k,V v,Entry<K,V> next,int hast){
this.k = k;
this.v = v;
this.next = next;
this.hast = hast;
}
public K getKey() {
return k;
}
public V getValue() {
return v;
}
}
}
我大概说一下put方法和get方法时间逻辑
put
首先定义一个数组,是16长度的,将存储的数据全部都存到这个数组中
当存储一个数据时算出他的hastcode值,把模16,得出的结果肯定是1到15
根据获取到的这个值获取对应位置的数组是否有值,如果没有值,直接把这个对应角标存进去
如果有值,则把这个值存当前这个对象当做一个参数存到这个对象中,把这个对象放到对应的角标位置上
get
这个自己把这段代码debug一下,更能对map加深印象
JDK1.8中
HashMap是数组、链表和红黑树组成的
在JDK8中在源码中put方法中有一个这个判断是否要使用红黑树
static final int TREEIFY_THRESHOLD = 8;
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
从这个我们看一看出来,当列表长度大于等于7的时候(也就是第8个)就会使用红黑树,在链表没有达到这个长度的时候一直还是和JDK7一样