Java源码角度分析HashMap用法

  

hashmap。   

优点:超级快速的查询速度,时间复杂度可以达到O(1)的数据结构非HashMap莫属。动态的可变长存储数据(相对于数组而言)。

  

缺点:需要额外计算一次哈希值,如果处理不当会占用额外的空间。

  

hashmap如何使用——

  

平时我们使用hashmap如下

        String> Map<整数;地图=new HashMap<整数,String> ();   地图。把(1,“a”);   地图。把(2 b);      

上面代码新建了一个HashMap并且插入了两个数据,这里不接受基本数据类型来做K、V
  

  

如果这么写的话,就会出问题了:

        Map地图=new HashMap ();      

我们为什么要这样使用呢?请看源码:

        公共类HashMap   扩展AbstractMap   实现Map可克隆,可序列化的      

这是HashMap实现类的定义。

  

hashmap是一个动态变长的数据结构,

  

在使用HashMap的时候,为了提高执行效率,我们往往会设置HashMap初始化容量:

        String> Map<字符串;rm=new HashMap<字符串,String> (2)      

或者使用番石榴的工具类地图,可以很方便的创建一个集合,并且,带上合适的大小初始化值。

        Object> Map<字符串;地图=Maps.newHashMapWithExpectedSize (7);      

那么为什么要这样使用呢?我们来看他们的源码构造函数。

  

未带参的构造函数:

        公共HashMap () {   这一点。负载系数=DEFAULT_LOAD_FACTOR;   阈值=(int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);   表=新条目(DEFAULT_INITIAL_CAPACITY);   init ();   }      

公共HashMap () {
  这一点。负载系数=DEFAULT_LOAD_FACTOR;
  阈值=(int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
  表=新条目(DEFAULT_INITIAL_CAPACITY);
  init ();
  }

     /* *   *构造一个空& lt; tt> HashMap</tt>与指定的初始   *能力和默认负载系数(0.75)。   *   * @param initialCapacity初始容量。   * @throws IllegalArgumentException如果初始容量是负的。   */公共HashMap (int initialCapacity) {   这个(initialCapacity DEFAULT_LOAD_FACTOR);   }      

名词解释:

        DEFAULT_LOAD_FACTOR//默认加载因子,如果不制定的话是0.75   DEFAULT_INITIAL_CAPACITY//默认初始化容量,默认是16   阈值//阈值(yu)根据加载因子和初始化容量计算得出,& lt;跨度微软yahei”;“在阈值表示当HashMap的大小大于阈值时会执行调整操作。      

因此我们知道了,如果我们调用无参数的构造方法的话,我们将得到一个16容量的数组。

  

所以问题就来了:如果初始容量不够怎么办?

  

数组是定长的,如何用一个定长的数据来表示一个不定长的数据呢,答案就是找一个更长的,但是在调整的时候是很降低效率的,所以我们建议HashMap的初始化的时候要给一个靠谱的容量大小。

  

hashmap的把方法——

        公共V把(K键,V值){   如果(键==null)//键为空的情况,HashMap和散列表的一个区别   返回putForNullKey(价值);   int散列=散列(key.hashCode ());//根据键的hashCode算出哈希值   int i=indexFor(散列,table.length);//根据哈希值算出究竟该放入哪个数组下标中   (Entrye=表(我);e !=零;e=e.next){//整的个循环实现了如果存在K那么就替换V   对象k;   如果(e。散列==散列,,((k=e.key)==关键| | key.equals (k))) {   V oldValue=https://www.yisu.com/zixun/e.value;   e。值=价值;   e.recordAccess(这个);   返回oldValue;   }   }      modCount + +,//计数器   addEntry(散列、关键值,我);//添加到数组中   返回null;   }      

如果插入的数据超过现有容量就会执行

        addEntry(散列、关键值,我),            空白addEntry (int散列,K键,V值,int bucketIndex) {   Entrye=表(bucketIndex);   表[bucketIndex]=new Entry(散列、关键值e);   如果(大小+ +祝辞=阈值)   & lt;跨度祝辞& lt; strong>调整(2 * table.length);   }      

Java源码角度分析HashMap用法