链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
LinkedList 是双向链表,列表中的每个节点都包含了对前一个和后一个元素的引用。
链表可分为单向链表和双向链表。
一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。
Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。
Node 为 LinkedList 的一个私有内部类,其定义如下,即定义了item(元素),next(指向后一个元素的指针),prev(指向前一个元素的指针)。
与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。
List 接口: List 是Collection的子接口,它是一个元素有序(按照插入的顺序维护元素顺序)、可重复、可以为null的集合。
AbstractList 类: List 接口的骨架实现类,最小化实现了 List 接口所需要实现的工作量。
Cloneable 接口: 实现了该接口的类可以显示的调用 Object.clone() 方法,合法的对该类实例进行字段复制,如果没有实现 Cloneable 接口的实例上调用 Obejct.clone() 方法,会抛出CloneNotSupportException 异常。正常情况下,实现了 Cloneable 接口的类会以公共方法重写Object.clone()方法。
Serializable 接口: 实现了该接口标示了类可以被序列化和反序列化。
Deque 接口: Deque 定义了一个线性 Collection,支持在两端插入和删除元素,Deque 实际是“double ended queue(双端队列)”的简称,大多数 Deque 接口的实现都不会限制元素的数量,但是这个队列既支持有容量限制的实现,也支持没有容量限制的实现,比如 LinkedList 就是有容量限制的实现,其最大的容量为 Integer.MAX_VALUE。
AbstractSequentialList 类: 提供了 List 接口的骨干实现,最大限度地减少了实现受“连续访问”数据存储(如链表) 支持的此接口所需的工作,对于随机访问数据(如数组),应该优先使用 AbstractList,而不是使用 AbstractSequentailList 类。
以下情况使用 ArrayList :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行插入和删除元素操作。
以下情况使用 LinkedList :
- 你需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行插入和删除元素操作。
import java.util.LinkedList;
import java.util.List;
//E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
List<E> s = new LinkedList<E>();
注意:
LinkedList 是非线程安全的。
LinkedList 元素允许为 null,允许重复元素。
LinkedList 是基于链表实现的,因此插入删除效率高,查找效率低。
LinkedList 是基于链表实现的,因此不存在容量不足的问题,所以没有扩容的方法。
LinkedList 还实现了栈和队列的操作方法,因此也可以作为栈、队列和双端队列来使用。
LinkedList 和 ArrayList 的效率比较:
顺序插入速度 ArrayList 会比较快,因为 ArrayList 是基于数组实现的,数组是事先 new 好的,只要往指定位置 塞一个数据就好了。
LinkedList 则不同,每次顺序插入的时候 LinkedList 将 new 一个对象出来,如果对象比较大,那么 new 的时间 势必会长一点,再加上一些引用赋值的操作,所以顺序插入 LinkedList 必然慢于 ArrayList 。
ArrayList 的遍历效率会比 LinkedList 的遍历效率高一些。
LinkedList 做插入、删除的时候,慢在寻址,快在只需要改变前后 Node 的引用地址。
ArrayList 做插入、删除的时候,慢在数组元素的批量 copy,快在寻址。
如果确定插入、删除的元素是在前半段,那么就使用 LinkedList。
如果确定插入、删除的元素在比较靠后的位置,那么可以考虑使用 ArrayList,如果不能确定插入、删除是在哪儿呢?建议使用 LinkedList。
一来 LinkedList 整体插入、删除的执行效率比较稳定,没有 ArrayList 这种越往后越快的情况。
二来插入元素的时候,弄得不好 ArrayList 就要进行一次扩容,而 ArrayList 底层数组扩容是一个既消 耗时间又消耗空间的操作。
Modifier and Type | Method and Description |
---|---|
boolean | add(E e) 将指定的元素追加到此列表的末尾。 |
void | add(int index, E element) 在此列表中的指定位置插入指定的元素。 |
boolean | addAll(Collection<? extends E> c) 按照指定集合的迭代器返回的顺序将指定集合中的所有元素追加到此列表的末尾。 |
boolean | addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始。 |
void | addFirst(E e) 在该列表开头插入指定的元素。 |
void | addLast(E e) 将指定的元素追加到此列表的末尾。 |
void | clear() 从列表中删除所有元素。 |
Object | clone() 返回此 |
boolean | contains(Object o) 如果此列表包含指定的元素,则返回 |
Iterator<E> | descendingIterator() 以相反的顺序返回此deque中的元素的迭代器。 |
E | element() 检索但不删除此列表的头(第一个元素)。 |
E | get(int index) 返回此列表中指定位置的元素。 |
E | getFirst() 返回此列表中的第一个元素。 |
E | getLast() 返回此列表中的最后一个元素。 |
int | indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 |
int | lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 |
ListIterator<E> | listIterator(int index) 从列表中的指定位置开始,返回此列表中元素的列表迭代器(按适当的顺序)。 |
boolean | offer(E e) 将指定的元素添加为此列表的尾部(最后一个元素)。 |
boolean | offerFirst(E e) 在此列表的前面插入指定的元素。 |
boolean | offerLast(E e) 在该列表的末尾插入指定的元素。 |
E | peek() 检索但不删除此列表的头(第一个元素)。 |
E | peekFirst() 检索但不删除此列表的第一个元素,如果此列表为空,则返回 |
E | peekLast() 检索但不删除此列表的最后一个元素,如果此列表为空,则返回 |
E | poll() 检索并删除此列表的头(第一个元素)。 |
E | pollFirst() 检索并删除此列表的第一个元素,如果此列表为空,则返回 |
E | pollLast() 检索并删除此列表的最后一个元素,如果此列表为空,则返回 |
E | pop() 从此列表表示的堆栈中弹出一个元素。 |
void | push(E e) 将元素推送到由此列表表示的堆栈上。 |
E | remove() 检索并删除此列表的头(第一个元素)。 |
E | remove(int index) 删除该列表中指定位置的元素。 |
boolean | remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 |
E | removeFirst() 从此列表中删除并返回第一个元素。 |
boolean | removeFirstOccurrence(Object o) 删除此列表中指定元素的第一个出现(从头到尾遍历列表时)。 |
E | removeLast() 从此列表中删除并返回最后一个元素。 |
boolean | removeLastOccurrence(Object o) 删除此列表中指定元素的最后一次出现(从头到尾遍历列表时)。 |
E | set(int index, E element) 用指定的元素替换此列表中指定位置的元素。 |
int | size() 返回此列表中的元素数。 |
Spliterator<E> | spliterator() 在此列表中的元素上创建late-binding和故障快速 |
Object[] | toArray() 以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。 |
<T> T[] | toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型。 |