持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
Collection子接口之List
ArrayList、Vector、LinkedList的区别?
ArrayList是List的主要实现类,底层使用Object[ ]存储,适用于频繁的查找工作,线程不安全 ;ArrayList还实现了RandomAccess接口,也就标识了ArrayList支持快速随机访问功能。Vector是List的古老实现类,底层使用Object[ ]存储,线程安全的。LinkedList底层使用双向链表进行存储,适用与头尾插入或删除元素,时间复杂度是O(1),但如果要在指定位置插入删除元素,时间复杂度为O(n)。
ArrayList的扩容机制
以无参构造器创建ArrayList为例。
首先调用add()方法,添加元素之前,会调用ensureCapacityInternal()方法,得到minCapacity的值。如果是第一次执行add方法,minCapacity为默认值10。
之后调用ensureExplicitCapacity()方法,来判断是否需要扩容。如果minCapacity - 数组长度 > 0 ,则说明当前数组长度不够用,需要调用grow()方法扩容。
grow()方法内部首先获取旧的数组大小,右移一位,将新的数组大小扩容为原来的1.5倍。如果扩容后的大小还小于minCapacity,那么当前容量就设置为minCapacity。
如果新容量大于MAX_ARRAY_SIZE,就比较旧容量和MAX_ARRAY_SIZE的大小,如果小于的话新容量大小则为 MAX_ARRAY_SIZE,否则即为Integer.MAX_VALUE。
Collection子接口之Set
comparable和Comparator的区别?
comparable接口出自java.lang包。它有一个compareTo(Object obj)方法用来排序comparator接口出自 java.util 包。它有一个compare(Object obj1, Object obj2)方法用来排序
无序性和不可重复性是什么?
- 无序性是指存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定。
- 不可重复性是指添加的元素按照equals()判断时,返回false。需要重写equals()和hashCode()。
HashSet、LinkedHashSet、TreeSet三者异同?
-
相同:三者都是线程不安全的,可以保证元素唯一。
-
不同:底层数据结构不同,导致应用场景不同。
HashSet底层使用哈希表。
LinkedHashSet底层使用链表和哈希表,元素插入取出满足FIFO。
TreeSet底层数据结构是红黑树,元素有序,可以使用自然排序和定制排序。
Collection子接口之Queue
Queue与Deque的区别?
Queue是单端队列,Deque是双端队列,可以在队列的两端进行插入或删除元素。
ArrayDeque与LinkedList的区别?
ArrayDeque 和 LinkedList 都实现了 Deque 接口。
ArrayDeque是基于可变长的数组和双指针来实现,而LinkedList则通过链表来实现。ArrayDeque不支持存储NULL数据,但LinkedList支持。ArrayDeque是在 JDK1.6 才被引入的,而LinkedList早在 JDK1.2 时就已经存在。ArrayDeque插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。虽然LinkedList不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。
PriorityQueue了解多少?
PriorityQueue利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据PriorityQueue通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。PriorityQueue是线程不安全的,且不支持存储NULL和non-comparable的对象。PriorityQueue默认是小顶堆,升序排序。但可以接收一个Comparator作为构造参数,从而来自定义元素优先级的先后。