Java集合框架
Collection和Map是Java集合框架的根接口,包含了一些子接口和实现类
- Set继承Collection,元素不重复
- HashSet和TreeSet实现里Set接口
- List接口继承Collection,允许重复,类似数组,长度可变,有序集合
- LinkedList、ArrayList、Vector实现了List接口
- Map接口是一个键值(KV)映射的接口,和Collection接口无关,元素可以重复,但是键唯一
- HashMap、LinkedHashMap、TreeMap实现了Map接口
Collection和Collections的区别
- Collection是集合的上级接口
- Collections就是一个工具类,提供一系列静态方法,和对集合的操作
HashMap
HashMap的扩容因子=0.75,初始大小是16
底层是数组+链表,jdk1.8之后从链表转到红黑树。put方法传递键值时,先对key做一个hashCode的计算,得到它在数组中的位置。获取对象通过get方法,找到桶的位置
hashMap的put方法
- 计算关于key的hashCode的值
- 散列表为空,通过resize方法初始化散列表
- 没发生hash碰撞,就直接添加元素
- 如果发生碰撞,有三种可能
- 如果equals结果为true,直接替换旧值
- 如果是红黑树结构就调用树的插入方法
- 如果是链表结构,就先遍历链表,插入之后判断链表个数是否达到变成红黑树的阈值,达到就转为红黑树储存
- 然后再判断桶满没满,如果桶满了就进行扩容
LinkedHashMap
继承了HashMap,增加一条双向链表,保证插入顺序
HashTable
- HashMap允许null值,HashTable不允许
- HashTable是线程安全的,接口有synchronized修饰
- HashMap是fail-fast快速失败迭代器,会抛出ConcurrentModification异常,HashTable不抛
- hash算法不同,HashMap自定义的哈希算法,HashTable直接用key的hashCode
- 扩容方式不同
- 但是现在一般不建议用 HashTable
- 遗留类,内部很多冗余
- 现在都用ConcurrentHashMap,效率更高
Iterator迭代器
提供了对集合元素的迭代方法
快速失败fail-fast和安全失败fail-save
- 快速失败:迭代一个集合的时候,有另一个线程访问这个集合,就会抛出ConcurrentModification异常
- 安全失败:迭代时在底层集合有一个拷贝,修改集合不受影响,不会抛出ConcurrentModification异常
Comparable 和 Comparator 的区别
- Comparable,用于一个对象和其他对象对比,核心方法是compareTo,只用传一个参数
返回值大于0表示对象大于参数对象
小于0表示对象小于参数对象
等于0表示对象等于参数对象 - Comparator,用于比较两个对象,核心方法是compare,要传两个参数
返回1说明第一个参数大于第二个参数
返回-1说明第二个参数大于第一个参数
返回0说明两个参数相等
List和Set
-
List:元素有序,可重复
-
Set:元素无序,不可重复
-
Set检索指定元素效率高,删除插入效率高
-
List可以动态增长,查找指定元素效率低,插入删除效率低
-
但是随机访问指定List比Set快
List和Map
- List是对象集合,对象可以重复
- Map是键值对集合,key不能重复
Array和ArrayList
- ArrayList不能存基本类型,储存时需要自动装箱
- ArrayList可以先声明,Array声明同时必须实例化
- Array只能存类型相同的对象,ArrayLIst可以存类型不同的对象
ArrayList和LinkedList
- ArrayList实现了动态数组,地址连续所以查询效率高
- LinkedList基于链表结构,开辟空间不需要等连续的地址,新增删除操作更快
- 但是我自己测试的结果,在数据量大的情况下还是ArrayList增删效率更快
ArrayList与Vector
Vector和ArrayList都是数组实现
Vector是多线程安全的,效率低,一般不用
Vector可以设置增长因子,ArrayList不行
HashSet 和TreeSet
HashSet是hash表实现的,增删元素的时间复杂度是O1
TreeSet是树形结构实现的,增删元素的时间复杂度是OlogN
HashMap和ConcurrentHashMap
- ConcurrentHashMap对整个桶数组进行了分割,每个被分割的分段上都用锁进行保护,相比HashTable的锁粒度更精细了,性能更好
- JDK8之后,ConcurrentHashMap利用CAS算法保证线程安全
- CAS通过Unsafe类里的native方法,访问底层操作系统,实现原子操作,内部定义值用volatile修饰,保证有序性和可见性
- CAS会有ABA问题,一个值由A变为B,再由B变为A,使用CAS操作无法感知到该种情况下出现的变化。可以通过每次修改都带上时间戳解决
队列和栈的区别
都用来预存储数据
队列先进先出
栈是后进先出
队列是接口,栈是类