Java集合
常用的集合类有哪些?
List,Set,Map三者的区别?
- List :有序集合(有序指存入的顺序和取出的顺序相同,不是按照元素的某些特性排序),可存储重复元素,可存储多个 null 。
- Set :无序集合(元素存入和取出顺序不一定相同),不可存储重复元素,只能存储一个 null 。
- Map :使用键值对的方式对元素进行存储, key 是无序的,且是唯一的。 value 值不唯一。不同的 key 值可以对应相同的 value 值。
常用集合框架底层数据结构
- List:
- ArrayList :数组
- LinkedList :双线链表
- Set :
- HashSet :底层基于 HashMap 实现, HashSet 存入读取元素的方式和 HashMap 中的 Key 是
一致的。 - TreeSet :红黑树
- HashSet :底层基于 HashMap 实现, HashSet 存入读取元素的方式和 HashMap 中的 Key 是
- Map :
- HashMap : JDK1.8之前 HashMap 由数组+链表组成的, JDK1.8之后有数组+链表/红黑树组成,当链表长度大于8时,链表转化为红黑树,当长度小于6时,从红黑树转化为链表。这样做的目的是能提高 HashMap 的性能,因为红黑树的查找元素的时间复杂度远小于链表。
- HashTable :数组+链表
- TreeMap :红黑树
哪些集合类是线程安全的?
- Vector :相当于有同步机制的 ArrayList
- Stack :栈
- HashTable
- enumeration :枚举
Java集合的快速失败机制 “fail-fast”和安全失败机制“failsafe”是什么?
- 快速失败
Java的快速失败机制是Java集合框架中的一种错误检测机制,当多个线程同时对集合中的内容进行修改时可能就会抛出 ConcurrentModificationException 异常。其实不仅仅是在多线程状态下,在单线程中用增强 for 循环中一边遍历集合一边修改集合的元素也会抛出ConcurrentModificationException 异常。
单线程的情况,用迭代器调用 remove() 方法即可正常运行
在多线程的情况下还是会报ConcurrentModificationException 异常
原因是:线程1更新了 modCount 和属于自己的expectedModCount ,而在线程2看来只有 modCount 更新了, expectedModCount 并未更新,所以会抛出 ConcurrentModificationException 异常
- 安全失败
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会抛出 ConcurrentModificationException 异常。缺点是迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生了修改,迭代器是无法访问到修改后的内容。java.util.concurrent 包下的容器都是安全失败,可以在多线程下并发使用。
List集合
ArrayList的扩容机制
ArrayList 的初始容量为10,扩容时对是旧的容量值加上旧的容量数值进行右移一位(位运算,相当于除以2,位运算的效率更高),所以每次扩容都是旧的容量的1.5倍。
ArrayList 和 LinkedList 的区别是什么?
- 是否线程安全: