【学习笔记】Java—Collection接口

93 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

Collection子接口之List

ArrayList、Vector、LinkedList的区别?

  • ArrayListList 的主要实现类,底层使用 Object[ ]存储,适用于频繁的查找工作,线程不安全 ;ArrayList还实现了RandomAccess接口,也就标识了ArrayList支持快速随机访问功能。
  • VectorList 的古老实现类,底层使用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的区别?

ArrayDequeLinkedList 都实现了 Deque 接口。

  • ArrayDeque 是基于可变长的数组和双指针来实现,而 LinkedList 则通过链表来实现。
  • ArrayDeque 不支持存储 NULL 数据,但 LinkedList 支持。
  • ArrayDeque 是在 JDK1.6 才被引入的,而LinkedList 早在 JDK1.2 时就已经存在。
  • ArrayDeque 插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。虽然 LinkedList 不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。

PriorityQueue了解多少?

  • PriorityQueue 利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据
  • PriorityQueue 通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。
  • PriorityQueue 是线程不安全的,且不支持存储 NULLnon-comparable 的对象。
  • PriorityQueue 默认是小顶堆,升序排序。但可以接收一个 Comparator 作为构造参数,从而来自定义元素优先级的先后。