HashMap源码学习小结

HashMap基本知识

  1. 链表数组,使用散列函数定位位置,链表的元素是Entry< key,value>
    HashMap源码学习小结_第1张图片
  2. 查询性能O(1),增删性能O(1)
  3. 非线程安全,使用modCount字段实现快速失败的功能
  4. 在table长度小于阈值(1 << 30)的情况下,能够自动扩容
  5. 定位的算法:
    1. 取key.hashCode进行hash函数运算,得出运算结果h
    2. 将h和table.length进行计算:h & (table.length - 1)
    3. 取table[index] 的链表,对key进行比较(hash值的比较,equal比较)
  6. 4个构造函数
    1. 使用默认 table大小和loadfactor
    2. 指定table大小
    3. 指定loadfactor
    4. 使用存在的HashMap

问题总结

  1. 能否存储key为null的元素?
    可以,存在table[0]的链表里
  2. HashMap啥时候resize table?
    当map中元素的总数量size大于threshold
  3. loadfactor的作用
  4. threshold 的作用
    threshold = (int)Math.min(table.length * loadFactor, MAXIMUM_CAPACITY + 1);
    用来控制hashMap中元素的总数量。当总数量size大于threshold 的时候,就需要进行扩容操作了。

主要源码

get方法:

get(key){
  hash = hash(key.hashcode()); //计算出key的hash函数结果
  for(Entry e:table[indexForKey(hash,table.lenght) ; e!=null ; e=e.next()]){
      if(hash == e.hash && ((k = e.key) == key || (k != null &&  k.equal(key)))){
        return e.value;
      }
  }
  return null;
}

put方法:
定位方法类似get。找到位置,且没有相同的key的情况下。新增一个,如果key相同就替换原来的value
涉及到table大小的调整

put(key,value):
if(table == EMPTY_TABLE)
{
  inflateTable(threshold);
}
if(key == null){
    return putForNullKey(value);
  }
int hash = hash(key.hashcode()); //计算出key的hash函数结果
int index = indexFor(hash,table.length);
for(Entry e:table[indexForKey(hash,table.lenght) ; e!=null ; e=e.next()]){
  if(hash == e.hash && ((k = e.key) == key || (k != null &&  k.equal(key)))){
        V oldValue = e.value;
        e.value = value;
        e.recordAccess(this);
        return oldValue;
  }
}
modCount++;
addEntry(hash,key,value,index);
return null;

addEntry():

你可能感兴趣的:(Java,源码学习)