参考文章: https://blog.csdn.net/jianyuerensheng/article/details/51579091

HashMap API—— 基于哈希表来实现的Map接口。其实现了map的所有方法,并允许空值和空键。(HashMap类大致等同于Hashtable,除了它是非同步的并且允许空值。) 这个类不保证map的顺序;特别是,它不保证顺序会随着时间的推移保持不变。 (key:是一个对象, value: 可以是个对象,也可以是个map)

一、HashMap的数据结构

1. HashMap - 图1 实现原理: 数组+linkedList
LinkedList作用: 解决hash冲突

二、CRUD

1. 构造函数

    1. 初始容量: 创建hash表时的容量;
    1. 加载因子:表示哈希表在其容量自动增加之前可以达到多满的一种程度;一般是0.75
    1. 容量翻倍: rehash()
      1. HashMap();//构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
      2. HashMap(int initialCapacity);//构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
      3. HashMap(int initialCapacity, float loadFactor);//构造一个带指定初始容量和加载因子的空 HashMap。
      4. HashMap(Map<? extendsK,? extendsV> m); //构造一个映射关系与指定 Map 相同的 HashMap。

      2. 存储的实现过程

      用hash表(也称为散列表)来管理所有元素;
      bucketIndex:当调用put()存值时,会首先调用key的hashcode()方法获取哈希码,即bucketIndex;
      碰撞: 当bucketIndex相同时,才会调用equals()方法进行比较;
      1. HashMap - 图2

三、HashMap和多线程相关问题

HashMap是线程不安全的实现,而HashTable是线程安全的实现。所谓线程不安全,就是在多线程情况下直接使用HashMap会出现一些莫名其妙不可预知的问题,多线程和单线程的区别:单线程只有一条执行路径,而多线程是并发执行(非并行),会有多条执行路径。如果HashMap是只读的(加载一次,以后只有读取,不会发生结构上的修改),那使用没有问题。那如果HashMap是可写的(会发生结构上的修改),则会引发诸多问题,如上面的fail-fast,也可以看下这里,这里就不去研究了。
那在多线程下使用HashMap我们需要怎么做,几种方案:
1.在外部包装HashMap,实现同步机制
2.使用Map m = Collections.synchronizedMap(new HashMap(…));,这里就是对HashMap做了一次包装
3.使用java.util.HashTable,效率最低
4.使用java.util.concurrent.ConcurrentHashMap,相对安全,效率较高
————————————————
版权声明:本文为CSDN博主「jianyuerensheng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jianyuerensheng/article/details/51579091