1.定义
Java Collections框架包含了大量的集合接口以及这些接口的实现类的操作它们的算法(排序、查找、反转、替换、复制、取最小值、取最大值)
2.Set
- 集中的元素不能重复,Set中定义的每一个元素通过定义equals()方法来确保对象的唯一性。如果Set中存放的对象,是通过比较对象的HashCode来确定唯一性。如果想要比较两个对象是否相等则需要重写hashCode() 和equals(Object o)这两个方法。
- 该接口有两个实现类:HashSet和TreeSet
2.1:TreeSet实现了SortSet接口;所以TreeSet中得元素是有序的,底层基于二叉树的原理对添加的元素进行排序。
2.2:HashSet:存放的散列值,元素的散列值是通过hashCode计算得知。
3.List
- List又称为有序的Collection,它按照对象进入的顺序来保存对象;
- 可以保存重复的对象;
- 可以存储重复的null值;
- 实现类有:LinkedList、ArrayList、Vector
ArrayList
基于数组实现,查找快,增删慢,线程不安全
细节
- 数组默认容量为10;
- 最大容量为整型地方最大值 Integer.MAX_VALUE;
- 扩容时机:添加的元素时,所需最小容量小于当前容量触发扩容;
- 扩容规则:为原来容量的1.5倍。
例如当前List中有10个元素,容量为10,此时去添加一个元素,那么最小容量大小为11,11小时当前的容量10。那么进行扩容,扩容后的容量为15; since JDK 1.2
。
Vector
基于数组实现,查找快,增删慢,线程安全
细节
- 扩容过程几乎和ArrayList一样,不同的是Vector扩容的容量为原来的2倍;
since JDK1.0
LinkedList
基于双向链表,查找慢,增删快,线程不安全,since JDK 1.2
。
Collections.SynchronizedList()
Collections工具类提供的基于同步锁实现的线程安全的List
CopyOnWriteArrayList
- JUC包下的线程安全的并发容器List,内部通过ReentrantLock、volatile修饰底层数组、写操作的时候赋值数组这些操作来保证线程安全。
@since 1.5
。
4.Map
- 值只可以重复,键不可以重复
- 实现类有HashMap、TreeMap、LinkedHashMap、WeakHashMap和IdentityHashMap
- HashMap是基于散列表实现的,采用HashCode可以进行快速查询;
- LinkedHashMap:采用列表来维护内部的顺序(按照进入的顺序保存);
HashMap
- 根据键的HashCode来存储数据,根据键可以很快直接获得它的值,具有很快的访问速度;
- 最多允许一条记录为空,key和value都可以为null;
- 线程不安全;
- 存入的键值在取出的时候没有固定的顺序,是随机的;
@since 1.2
.
细节
- 在HashMap中,hash数组的默认大小是16,而且是2的倍数;
- JDK1.7以前采用数组+链表的存储数据;JDK1.8后使用数组+链表+红黑树
LinkedHashMap
- linkedHashMap是HashMap一个子类,输入的顺序和输出的顺序相同;
@since 1.4
。
HashTable
线程安全
- 使用Enumeration遍历
- 默认数组大小是11,增加的方式是:old*2+1
- key和value都不能为null;
@since JDK1.0
。
TreeMap
- 基于红黑树的数据结构来实现的,内部元素是按需排序的。
- 实现了SortMap接口,能够把它保存的记录根据键排序。所以取出来的是排序后的键值对;
- key不可以为null;
@since 1.2
。
Collections.SynchronizedMap
和 Collections.SynchronizedList一样,也是Collections工具类提供同步容器Map。内部可以通过synchronized同步对象来达到线程安全的。
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
ConcurrentHashMap
@since 1.5
;- JUC包下提供线程安全的Map实现类。
总结
各个集合对是否支持null
类 | 是否支持null |
---|---|
ArrayList | 是,可以存放多个null |
Linked | 是,可以存放多个null |
Vector | 是,可以存放多个null |
HashMap | key和value都可以为null |
HashTable | key和value都不能为null |
TreeMap | key不能为null,value可以为null |
LinkedHashMap | 继承于HashMap,key和value都可以为null |
ConcurrentHashMap | key和value 都不能为null |
HashSet | 可以为null |
TreeSet | 否,不能存储null值 |
常见面试题
HashMap 和 HashTable 有什么区别
- 出现的版本不同:HashTable是JDK1.0出现的,HashMap 是JDK1.2中出现的;
- 安全性:HashMap 是线程不安全的,HashTable 是线程安全的;
- hash计算规则不同:HashMap 的键需要重新计算对象的 hash 值,而 HashTable 直接使用对象的 hashCode;
- 对于null的处理逻辑不同:HashMap 的值和键都可以为 null,HashTable 的值和键都不能为 null;
- 初始化大小不同:HashMap 的数组的默认初始化大小为 16,HashTable 为 11;
- 扩容细节不同:HashMap 扩容时会扩大两倍,HashTable 扩大两倍 + 1
Vector和 ArrayList的有什么区别
和上面一样 可用从版本号、底层存储数据的元素、默认容量、扩容后的容量、安全性这些方面进行说明。