LinkedList即底层基于链表的线性表
当业务中查询少,但需要频繁增,删的场合可使用LinkedList替代ArrayList。
特点:
- 底层基于链表,不存在初始化容器大小,也不用自动扩容
- 新增/删除元素平均时间复杂度: O(n)
- 查找元素平均时间复杂度:O(n)
- LinkedList除了作为普通的线性链表,还可以作为Java标准的栈和队列实现。所以它的接口要比ArrayList多很多。
LinkedList主要方法
作为普通链表
-
初始化
通过new LinkedList() 或 new LinkedList(Collection c)初始化一个链表 -
add(int index, E e)
在指定索引位新增一个元素,先找到index位的结点,然后将新结点插入到指定位置即可 -
get(int index)
返回指定索引位的元素,实现也很简单,即从链表的头开始遍历到指定的索引位即可。 相比ArrayList的实现,它的时间复杂度比较高是O(n) -
remove(int index)
删除指定索引位的元素,相比ArrayList实现比较简单,不需要移位
作为栈(stack)
- 初始化空栈
new LinkedList()
- 压栈(push)
push(E e)
- 出栈(pop)
pop()
- 取栈顶元素(peek)
peek()
作为队列(Queue)
- 入列(offer)
boolean offer(E e);
元素入列到队尾
- 出列(poll)
E poll();
元素从队首出列
- 取队首元素(peek)
E peek();
作为双端队列(Deque)
- 队首入列(offerFirst)
boolean offerFirst(E e);
- 队尾入列(offerLast)
boolean offerLast(E e);
- 队首出列(pollFirst)
E pollFirst();
- 队尾出列(pollLast)
E pollLast();
- 取队首元素(peekFirst)
E peekFirst();
- 取队尾元素(peekLast)
E peekLast();
源码分析
- add(int index, E element); E remove(int index)
/**
* Inserts the specified element at the specified position in this list.
* Shifts the element currently at that position (if any) and any
* subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
// 检查index范围, 0 <= index <= size
checkPositionIndex(index);
// 元素插入到末尾
if (index == size)
linkLast(element);
else // 非末尾,插入到index所在元素的前面
linkBefore(element, node(index));
}
/**
* Removes the element at the specified position in this list. Shifts any
* subsequent elements to the left (subtracts one from their indices).
* Returns the element that was removed from the list.
*
* @param index the index of the element to be removed
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException {@inheritDoc}
* 移除操作非常简单,断开目标元素的上下指针即可
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
- push, pop, peek
/**
* Pushes an element onto the stack represented by this list. In other
* words, inserts the element at the front of this list.
*
* <p>This method is equivalent to {@link #addFirst}.
*
* @param e the element to push
* @since 1.6
*/
public void push(E e) {
addFirst(e);
}
/**
* Pops an element from the stack represented by this list. In other
* words, removes and returns the first element of this list.
*
* <p>This method is equivalent to {@link #removeFirst()}.
*
* @return the element at the front of this list (which is the top
* of the stack represented by this list)
* @throws NoSuchElementException if this list is empty
* @since 1.6
*/
public E pop() {
return removeFirst();
}
/**
* Retrieves, but does not remove, the head (first element) of this list.
*
* @return the head of this list, or {@code null} if this list is empty
* @since 1.5
*/
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
栈的三个操作非常简单,就是只从头这一端操作。
- offer, poll, peek
/**
* Adds the specified element as the tail (last element) of this list.
* 入列操作即将元素加入到队尾
* @param e the element to add
* @return {@code true} (as specified by {@link Queue#offer})
* @since 1.5
*/
public boolean offer(E e) {
return add(e);
}
/**
* Retrieves and removes the head (first element) of this list.
* 出列操作即从队首取出元素
* @return the head of this list, or {@code null} if this list is empty
* @since 1.5
*/
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
/**
* Retrieves, but does not remove, the head (first element) of this list.
* 获取队首元素,即取首元素
* @return the head of this list, or {@code null} if this list is empty
* @since 1.5
*/
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
- offerFirst, offerLast, pollFirst, pollLast, peekFirst, peekLast
双端队列的操作
/**
* Inserts the specified element at the front of this list.
*
* @param e the element to insert
* @return {@code true} (as specified by {@link Deque#offerFirst})
* @since 1.6
*/
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
/**
* Inserts the specified element at the end of this list.
*
* @param e the element to insert
* @return {@code true} (as specified by {@link Deque#offerLast})
* @since 1.6
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
/**
* Retrieves, but does not remove, the first element of this list,
* or returns {@code null} if this list is empty.
*
* @return the first element of this list, or {@code null}
* if this list is empty
* @since 1.6
*/
public E peekFirst() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
/**
* Retrieves, but does not remove, the last element of this list,
* or returns {@code null} if this list is empty.
*
* @return the last element of this list, or {@code null}
* if this list is empty
* @since 1.6
*/
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
}
/**
* Retrieves and removes the first element of this list,
* or returns {@code null} if this list is empty.
*
* @return the first element of this list, or {@code null} if
* this list is empty
* @since 1.6
*/
public E pollFirst() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
/**
* Retrieves and removes the last element of this list,
* or returns {@code null} if this list is empty.
*
* @return the last element of this list, or {@code null} if
* this list is empty
* @since 1.6
*/
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
}
// 双端队列的操作非常简单,队首和队尾同时支持入列,出列和取元素