Android基础-Collection之List系列

黎浩然
2023-12-01

List<E>是Collection<E>接口的子接口。

 

让我们学习一波常用的List<E>接口的实现类吧,你都知道哪些?

今天我们学习四个:ArrayList、LinkedList、Stack、CopyOnWriteArrayList

 

在学之前,看看List的特点吧!

List接口:

List是有序的Collection,使用此接口可以精确的控制每个元素插入的位置,类似于数组,用户可以使用索引来访问List中的元素。和set不同,元素可以重复。

List相比Collection:

  • List提供了一种特殊的iterator遍历器,叫做ListIterator。这种遍历器允许遍历时插入,替换、删除、双向访问。并且还有一个重载方法允许从一个指定位置开始遍历。

 

  • List在原来的Collection的基础上,List是一个可以指定索引,有序的容器。

 

ArrayList(数组):

ArrayList实现了可变大小的数组,它允许所有的元素,包括null。ArrayList没有同步。

ArrayList线程不安全,内部不是原子操作。

 

Vector:

vector非常类似ArrayList,但是Vector是同步的。当一个线程正在迭代的时候,另一个线程改变Vector状态,会抛异常。

 

LinkedList(双向链表):

LinkedList实现了List接口,允许null元素,此外LinkedList提供了额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(Stack)、队列(Queue)或者双向队列(deque)

 

Stack:

stack继承Vector,先进后出的栈。

 

CopyOnWriteArrayList:

答:CopyOnWriteArrayList用于读多写少的并发场景,比如白名单、黑名单。

CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

CopyOnWriteArrayList(免锁容器)的好处之一是多个迭代器同时遍历和修改这个列表时,不会抛出ConcurrentModificationException。在CopyOnWriteArayList中,写入将会导致创建整个底层数组的副本,而源数组将保留在原地,使得复制的数组在被修改时,读取操作可以安全地执行。

 

 

 

问题1:ArrayList和LinkedList各自的特点,你怎么看?

问题2:ArrayList与LinkedList的使用场景和数据结构。

 

问题1:我感觉这个就跟问数组和链表的区别没什么区别,哈哈。

ArrayList其实是包装了一个数组 Object[],当实例化一个ArrayList时,一个数组也被实例化,当向ArrayList中添加对象是,数组的大小也相应的改变。这样就带来以下有缺点:

快速随即访问 你可以随即访问每个元素而不用考虑性能问题,通过调用get(i)方法来访问下标为i的数组元素。

向其中添加对象速度慢 当你创建数组是并不能确定其容量,所以当改变这个数组时就必须在内存中做很多事情。

操作其中对象的速度慢 当你要想数组中任意两个元素中间添加对象时,数组需要移动所有后面的对象。

 

LinkedList

LinkedList是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。这样就带来以下有缺点:

操作其中对象的速度快 只需要改变连接,新的节点可以在内存中的任何地方

不能随即访问 虽然存在get()方法,但是这个方法是通过遍历接点来定位的所以速度慢。

 

说白了,就是数据结构中的顺序存储和链式存储

 

问题2:

List实现 使用场景 数据结构

ArrayList 数组形式访问List链式集合数据,元素可重复,访问元素较快 数组

LinkedList 链表方式的List链式集合,元素可重复,元素的插入删除较快 双向链表

 

 

 类似资料: