目录
1方法
方法 | 描述 |
---|---|
public boolean add(E e) | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public void add(int index, E element) | 向指定位置插入元素。 |
public boolean addAll(Collection c) | 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。 |
public boolean addAll(int index, Collection c) | 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。 |
public void addFirst(E e) | 元素添加到头部。 |
public void addLast(E e) | 元素添加到尾部。 |
public boolean offer(E e) | 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerFirst(E e) | 头部插入元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerLast(E e) | 尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
public void clear() | 清空链表。 |
public E removeFirst() | 删除并返回第一个元素。 |
public E removeLast() | 删除并返回最后一个元素。 |
public boolean remove(Object o) | 删除某一元素,返回是否成功,成功为 true,失败为 false。 |
public E remove(int index) | 删除指定位置的元素。 |
public E poll() | 删除并返回第一个元素。 |
public E remove() | 删除并返回第一个元素。 |
public boolean contains(Object o) | 判断是否含有某一元素。 |
public E get(int index) | 返回指定位置的元素。 |
public E getFirst() | 返回第一个元素。 |
public E getLast() | 返回最后一个元素。 |
public int indexOf(Object o) | 查找指定元素从前往后第一次出现的索引。 |
public int lastIndexOf(Object o) | 查找指定元素最后一次出现的索引。 |
public E peek() | 返回第一个元素。 |
public E element() | 返回第一个元素。 |
public E peekFirst() | 返回头部元素。 |
public E peekLast() | 返回尾部元素。 |
public E set(int index, E element) | 设置指定位置的元素。 |
public Object clone() | 克隆该列表。 |
public Iterator descendingIterator() | 返回倒序迭代器。 |
public int size() | 返回链表元素个数。 |
public ListIterator listIterator(int index) | 返回从指定位置开始到末尾的迭代器。 |
public Object[] toArray() | 返回一个由链表元素组成的数组。 |
public T[] toArray(T[] a) | 返回一个由链表元素转换类型而成的数组。 |
2源码实现
2.1继承关系
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
LinkedList 继承自AbstractSequentialList(该类对通用方法做了实现,linkedlist可以直接继承使用)
实现接口:List、Deque、Cloneable、Serializable (Deque接口是队列的接口,提供了队列相应的方法)
2.2构造函数
//无参构造函数
public LinkedList() {
}
//有参构造 通过Collection集合实现类来实例化LinkedList
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
2.3属性信息
//集合中数据个数
transient int size = 0;
//头结点
transient Node<E> first;
//尾节点
transient Node<E> last;
//Node的声明如下:
private static class Node<E> {
E item; //存储元素
Node<E> next; //下一个
Node<E> prev; //上一份元素位置
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
2.4默认值或默认属性
无
2.5底层数据结构
LinkedList底层的数据结构是双向链表
2.6常用方法研究
2.6.1插入元素:add()
//插入节点
public boolean add(E e) {
//调用尾插法插入数据
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
//集合插入第一个节点时,first和last都为null,就将当前节点作为头节点
first = newNode;
else
//当原last节点存在时,原last的next指针指向当前新的节点
l.next = newNode;
size++;
modCount++;
}
2.6.2获取元素:get(int index)
public E get(int index) {
//index合法性校验
checkElementIndex(index);
return node(index).item;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
Node<E> node(int index) {
// assert isElementIndex(index);
//采用双向遍历形式 当index和size/2比较,小于size/2采用向后遍历,否则采用向前遍历,提高查询效率
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
2.6.3删除数据:remove(Object o)
public boolean remove(Object o) {
//删除元素是从fist头结点开始往后遍历,找每一个节点的元素和当前元素比较是否相等(== 或者equals)
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null ) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
//删除版本1 自定义实现,是考虑删除节点为first、last和中间节点三种情况
if (prev == null)
first = next;
next.prev = null;
else if (next == null) //尾节点
last = prev;
prev.next = null;
else //中间节点
prev.next = next;
next.prev = prev;
x.item = null;
x.prev = null;
x.next = null;
//删除版本2 JDK实现 考虑前驱节点和后驱节点两种节点情况
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
2.7应用场景
linkedlist的在变更操作(添加、删除)的时间复杂度趋近o(1),而在查询操作的时间复杂度是o(n)
因此:适用于增删操作较多的场景
3特点总结
①插入有序
②数据可以重复
③可以存储null值
④底层数据结构是链表