1. hashmap
实现map接口,按键值对存储,按键计算hash值,可直接用key值获取value对象,比较方便
new HashMap()时,不会分配数组空间,在第一次添加值时会初始化数组tab[],默认大小16,加载因子0.75,当map中对象个数到达阈值(默认基础阈值threshold=16*0.75)进行数组按threshold=threshold << 1两倍扩容
int index = (n - 1) & hash;// 对象节点所在数组下标
存放数字时无序,不可重复key值
底层是哈希表的数据结构,如下。这里提一下,hashmap在jdk1.8引入了红黑树结构
- 添加节点时,在jdk1.8中后面的链表在链表长度大于等于8时,会将链表转为红黑树结构;
- 在红黑树结构中,resize()时只有≦6的节点个数 或者 移除节点时根节点只有左子树或者右子树,将树转为普通链表
线程不安全
2. hashset
hashset是基于hashmap实现的,可以把它当成一个value为空的hashmap,是对hashmap的封装和利用。实现set接口,按对象存储,按存储对象计算hash值,要全部迭代才能一一读出对象。
存放数字时无序,不可重复值
底层数据结构与hashmap一致
线程不安全
3. HashTable
实现map接口,按键值对存储,按键计算hash值,可直接用key值获取value对象,比较方便
new HashTable()时,会分配数组空间tab[],默认大小11,加载因子0.75
底层是哈希表的数据结构
底层数据结构与hashmap一致
在涉及修改的方法上加上了synchronized关键字,线程安全
3. ArrayList
实现List接口,存放数据无序
默认1.5倍扩容
oldCapacity + (oldCapacity >> 1)
底层数据结构为数组
线程不安全
4. Vector & Stack
Stack就是把Vector数组封装成栈,关键操作加上了synchronized,线程安全
Vector底层数据结构为数组,与ArrayList基本一致,关键修改操作加上了synchronized,线程安全
Vector在未指定增长因子capacityIncrement时 是1倍扩容
oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity)
5. collection
数据集合的基本接口有两种,collection和map。实现collection接口的子接口有Set,List,Queue,他们的实现类应该很清楚了,是我们常用的hashset,arraylist等,collection是它们的公共接口。而这里想提到的是collection中的三个易混淆方法,用于集合的交并差集,retainAll,containsAll和removeAll:
boolean retainAll(Collection<?> c)
:调用此方法除去collection中不存在于c中的元素。换句话说,如果collection中的元素在c中没有找到,则会去掉collection中的这一元素,并且返回true(collection被改变则会返回true);如果collection中的所有元素在c中都可以找到,则不会改变collection并且返回false。这里也就是相当于一个另类的求两个集合的交集。
例如:
c1: 1,2,2
c2: 1,2
c1.retainAll(c2);//这里会返回false,因为c1中的元素在c2中都存在,不需要改变,则返回false
boolean containsAll(Collection<?> c)
:调用此方法判断collection是否包含c中的所有元素
boolean removeAll(Collection<?> c)
:调用此方法去掉所有collection中存在于c中的元素,和retainAll差不多,如果colletion没有改变,则返回false,否则返回true。这里也就是相当于一个另类的求两个集合的差集。
例如:
c1: 1,2,2,3
c2: 1,2
c1.removeAll(c2);//这里会返回true,因为c1中的元素在c2中都存在,c1中的元素除了3之外会被全部移除,c1最后输出只有3