HashMap源码分析

1.       HashMap 是基于哈希表的Map接口的实现。 

    这个实现提供了所有可选的映射操作,并且允许key与value为null

    HashMap类大致等同于Hashtable,除了它是不同步并允许空值。这个类没有保证map的顺序; 特别是不保证这个顺序

    将随时间保持不变。

 

 2.    

    这个实现为基础提供了恒定的性能

    操作get 和put ,假设散列函数在桶之间正确地分散元素。
 
    对收集视图的迭代需要 HashMap实例的“容量”(桶的数量)加上其大小(键值映射的数量)的时间比例。
              因此,如果迭代性能很重要,不要将初始容量设置得太高(或者负载因子太低)。
 
3.    

    一个hashMap有两个参数影响他的性能,初始容量和负载因子

    容量是散列表中桶的数量,以及初始值容量就是哈希表创建时的容量。

      “负载因子”是在哈希表的容量自动增加之前,哈希表得到多少容量的一种度量。

    当哈希表中的条目数量(number of entries)超过负载因子和当前容量的乘积时,哈希表被重新构造(即,内部数据结构被重建),使得哈希表具有大约 桶数的两倍。

 4.

 

一般来说,默认加载因子(.75)提供了时间和空间成本之间的良好折衷。

 

  较高的值会减少空间开销,但会增加查找成本(反映在大部分HashMap类的操作中,包括get和put)。

在设定其初始容量时,应考虑map中预期的数量及其载荷因子,以尽量减少

哈希表被重新构造的次数。

如果初始容量大于条目数量最大数除以负载因子,则不会发生重新刷新操作。

如果在HashMap实例中要存入很多元素,那么在初始化HashMap实例的时候,初始化一个足够大容量的实例,会更加有效的存储,而不是让它根据需要自动重新哈希来增长表。

 

5.

<p> <strong>请注意,此实现不同步。</ strong>
如果多个线程同时访问哈希映射,并且至少有一个
线程在结构上修改了地图,它必须被外部同步。

(结构修改是增加或删除一个或多个键值对(entrie),对已有key的value值的修改不是结构修改。)

这个一般是通过一些自然地封装的对象来完成同步的

如果没有这样的对象存在,map应该使用“包装”方法。 这最好在创作时完成,以防对map的不同步访问:

  Map m = Collections.synchronizedMap(new HashMap(...)); 

 

6.

所有这个类的“集合视图方法”返回的迭代器都是快速失败的:

如果地图在迭代器创建后的任何时候都在结构上被修改,
除了通过迭代器自己的<tt> remove </ tt>方法之外,迭代器将抛出{@link ConcurrentModificationException}异常。

因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未定的时间冒着任意的,不确定的行为冒险。

 

7.

    请注意,迭代器的快速失败无法得到保证,因为一般来说,在非同步并发修改的情况下无法做出任何硬性保证。

    快速失败会使 迭代器尽可能地抛出ConcurrentModificationException

    因此依赖这个异常而得到正确性,去编写一个程序是错误的

    迭代器的快速失败行为应该仅用于检测错误。

 

这个类是集合框架的一员

posted @ 2018-01-27 23:35  代码改变心态  阅读(181)  评论(0编辑  收藏  举报