Java集合之List

186 阅读2分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

List 是 Java 中常用集合之一,其重点实现类包括 ArrayList、LinkedList 和 Vector

ArrayList

ArrayList 是通过数组实现的,可以认为它是一个可改变容量的数组。其扩容增量为 0.5 倍。

  1. 为什么说 ArrayList 的底层是数组?

由其构造方法可以发现,当我们创建一个 ArrayList 对象时,其实就是创建了一个 Object 类型的数组。

 public ArrayList() {
     // DEFAULTCAPACITY_EMPTY_ELEMENTDATA 为 Object 类型的空数组
     this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 }
  1. 为什么 ArrayList 的容量可变,扩容增量又是多少呢?

由其扩容方法我们可以发现,ArrayList 每次扩容都为原数组容量的 1 / 2,然后将原数组的数据拷贝到新数组。因此,当我们创建数据时,尽量指定 ArrayList 的初始容量大小,以减少数组拷贝次数,提升数组创建效率。

 private void grow(int minCapacity) {
     int oldCapacity = elementData.length;
     // 扩容增量为原来的 1 / 2
     int newCapacity = oldCapacity + (oldCapacity >> 1);
     ...
     elementData = Arrays.copyOf(elementData, newCapacity);
 }

LinkedList

LinkedList 是通过双向链表实现的,因此也就没有扩容的概念。

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    ...
}

Vector

Vector 也是通过数组实现的,不过它的很多方法都用了 synchronized 修饰,因此是线程安全的。Vector 缺省情况下的增量为原数组容量的 1 倍。

当然 Vector 因为性能问题,已不再建议使用,为了保证线程安全,可以使用 synchronizedList

ArrayList 和 LinkedList 的区别

ArrayList 与 LinkedList 之间的区别,其实也就是数组与链表之间的区别。

数组查询和赋值比较快,因为可以通过数组下标访问指定位置的数据。

链表增加和删除比较快,因为可以通过修改链表的指针进行数据的增加和删除。

ArrayList 和 Vector 的区别

ArrayList 与 Vector 之间的区别,主要是 ArrayList 是线程不安全的,而 Vector 是线程安全的。

总结

扩容增量线程安全应用场景
ArrayList0.5 倍查找数据时间多
LinkedList-增删数据时间多
Vector1 倍多线程