一、HashMap
-
HashMap是Map接口使用频率最高的实现类。
-
HashMap是以键值对(key-value)形式存储数据。
-
key不能重复,值可以重复,允许使用null作为键或值。
-
添加相同的key,新的value将会覆盖原有的value。
-
不能保证存取顺序一样。
-
HashMap没有实现同步,线程不安全。
扩容机制:(和HashSet一模一样,详细源码解读可以去看
HashSet)
1.构造器:
可见其构造器仅初始化加载因子。
2.put方法:
put方法就是HashSet中add方法实际调用的方法,不做介绍了。
3.树化和剪枝:
HashMap 链表和红黑树的转换
二、HashTable
1.存放的是键值对。
2.键和值都不能为null。
3.方法与HashMap基本一致。
4.HashTable是线程安全的,HashMap是线程不安全的。
5.HashTable底层是数组+链表,不会变成二叉树,因此简单很多。
底层:
构造器:
可见,无参构造器调用自身的有参构造器,传入参数11和0.75f
然后在有参构造器中,经过判断之后,直接创建一个内部类Entry类型的数组,大小为11
然后在给threshold赋值。
可见其与HashMap不同,即使没有添加元素,也
put()添加元素:
首先判断数据是否为null,这一点和HashMap不一样,其不允许value为null。
然后然后hash得到带加入元素应该加入的位置index。
之后判断对应位置是否有元素,没有直接调用addEntry()方法并传入参数添加对应键值对。
有元素则判断对应链表每个元素,判断是否相等,如果相等则直接替换value,然后返回对应旧的值。
链表到底,依旧没有,则直接调用addEntry()加入。
最后返回null,可见返回null为正确加入。
addEntry():
先将modCount++,
然后判断count是否大于阈值,大于旧rehash()扩容,小于则直接加入。
rehash():
可见扩容是将旧的容量*2,然后+1.
与HashMap对比:
三、Properties
1.Properties类继承自Hashtable类,并实现了Map接口,也是使用键值对来保存数据。
2.与Hashtable类似。
3.Properties还可以用于从xxx.properties配置文件中,加载数据到Properties类对象并进行读取和修改。
4.因为其继承HashTabel,所以key和value不能有null。