这可能是第一次也是最全面的一次学习--HashMap

时光毁灭记忆、已成空白 提交于 2020-01-22 01:11:42

学习HashMap的第一天:

如何学习:

  • 1.从上到下的先总体过一遍
  • 2.对于其中一些特殊的地方进行特殊的处理
  • 3.融会贯通,总结在当中的特性和常见的面试问题
  • 4.拓展与应用

1.从上到下的看一遍(先注释):

1.点开HashMap源码(前面的小部分注释内容)

2.核心内容:

  • 1.HashMap的key和value可空,无序
  • 2.初始容量和负载因子决定性能
  • 3.线程不安全

3.从上到下啊开始看注释:

  • 基于哈希表实现的Map接口,允许key和value值为空,大致相当于hashtable(1) 只是它不同步,允许为空.这个类不能保证map的顺序,无法保证顺序会随时间变化

  • HashMap为基本功能提供了恒定时间的性能,假设使用哈希函数(散列函数)将元素适当的分散子各个同种,集合视图上的迭代需要的时间与模型的’容量(HashMap实例及其大小)'成正比.因此,如果迭代性能不佳,不要设置初始值或者设置负载因子过低(very importent)

  • HashMap中有两个参数会影响他的性能:初始容量负载因子.

    • 初始容量就是HashMap中桶的数量(每一个键值对占用的位置称之为桶),
    • 负载因子是衡量哈希表允许填充的程度的度量:在容量增加之前获取,当哈希表汇总的条目超过了(负载因数*容量),哈希表将会刷新(内部数据重建结构),以使哈希表扩容为大约原来的两倍.
  • 一般来说,默认的负载因子(0.75)在时间和空间成本之间提供了一个很好的权衡。更高的值减少了空间开销,但是增加了查找成本(反映在HashMap类的大多数操作中,包括get和put)。在设置其初始容量时,应考虑映射中的期望条目数及其负载因子,以最小化重哈希操作的数量。如果初始容量>(最大条目数/负载因子),则不会发生任何rehash(2)操作。

  • 如果要将许多映射存储在HashMap实例中,那么使用足够大的容量创建映射将比根据需要执行自动散列来扩展表更有效地存储映射。注意,使用多个具有相同hashCode()的键肯定会降低任何散列表的性能

  • 注意,这个实现不是同步的。如果多个线程同时访问一个散列映射,并且至少有一个线程从结构上修*改了该映射,则必须在外部对其进行同步。(结构修改是指增加或删除一个或多个映射的操作;仅仅更改与一个实例已经包含的键相关联的值并不是结构修改)

  • 如果不存在这样的对象,那么应该使用Collections synchronizedMap方法“包装”映射

    (Map m = Collections.synchronizedMap(new HashMap(...)))。// 为防止意外地不同步地访问,这最好在创建时完成
  • HashMap的所有“集合视图方法”返回的迭代器是fail-fast:如果在迭代器创建后的任何时候,以任何方式(除了通过迭代器自己的删除方法)对映射进行结构修改,迭代器将抛出’ConcurrentModificationException’。因此,在面对并发修改时,迭代器会快速而干净地失败,而不是在未来某个不确定的时间冒着任意的、不确定的行为的风险。

  • 通常来说,在存在非同步并发修改的情况下,迭代器的“fail-fast”行为不能得到保证,不可能做出任何严格的保证。“fail-fast”迭代器在最大努力的基础上抛出ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速故障行为应该只用于检测bug。

小总结:

HashMap的开始部分主要对其进行了一些说明.有了一个大致的了解,同时也有了一些其他的疑问,比如在开始强调的与hashmap的区别和在线程不安全时的一系列问题,这里做一个简单的注释,后面统一对这些问题进行处理.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!