1.介紹
LinkedList 是線程不安全的,允許元素爲null的雙向鏈表。就是這麼簡單
2.LinkedList繼承結構一覽圖
3.類定義
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
- Cloneable實現克隆
- Serializable序列化
- List 定義了一些集合類的方法
- Deque雙向隊列接口(就是兩端都可以進行增加刪除操作)
注意一點LinkedList並沒有實現RandomAccess所以隨機訪問是非常慢的。
在說LinkedList之前,先介紹下AbstractSequentialList,Deque,Queue,其他的已經在前面文章介紹過,詳情請查看
AbstractSequentialList
//此類提供List 接口的基本實現,以最大程度地減少實現由“順序訪問”數據存儲(例如鏈表)支持的接口所需的工作
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractSequentialList() {
}
/**
* Returns the element at the specified position in this list.
*
* <p>This implementation first gets a list iterator pointing to the
* indexed element (with {@code listIterator(index)}). Then, it gets
* the element using {@code ListIterator.next} and returns it.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
返回此列表中指定位置的元素
*/
public E get(int index) {
try {
return listIterator(index).next();
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
/**
* Replaces the element at the specified position in this list with the
* specified element (optional operation).
*
* <p>This implementation first gets a list iterator pointing to the
* indexed element (with {@code listIterator(index)}). Then, it gets
* the current element using {@code ListIterator.next} and replaces it
* with {@code ListIterator.set}.
*
* <p>Note that this implementation will throw an
* {@code UnsupportedOperationException} if the list iterator does not
* implement the {@code set} operation.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
用指定的元素替換此列表中指定位置的元素
*/
public E set(int index, E element) {
try {
ListIterator<E> e = listIterator(index);
E oldVal = e.next();
e.set(element);
return oldVal;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
/**
* Inserts the specified element at the specified position in this list
* (optional operation). Shifts the element currently at that position
* (if any) and any subsequent elements to the right (adds one to their
* indices).
*
* <p>This implementation first gets a list iterator pointing to the
* indexed element (with {@code listIterator(index)}). Then, it
* inserts the specified element with {@code ListIterator.add}.
*
* <p>Note that this implementation will throw an
* {@code UnsupportedOperationException} if the list iterator does not
* implement the {@code add} operation.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
將指定的元素插入此列表中的指定位置
*/
public void add(int index, E element) {
try {
listIterator(index).add(element);
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
/**
* Removes the element at the specified position in this list (optional
* operation). Shifts any subsequent elements to the left (subtracts one
* from their indices). Returns the element that was removed from the
* list.
*
* <p>This implementation first gets a list iterator pointing to the
* indexed element (with {@code listIterator(index)}). Then, it removes
* the element with {@code ListIterator.remove}.
*
* <p>Note that this implementation will throw an
* {@code UnsupportedOperationException} if the list iterator does not
* implement the {@code remove} operation.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
刪除此列表中指定位置的元素
*/
public E remove(int index) {
try {
ListIterator<E> e = listIterator(index);
E outCast = e.next();
e.remove();
return outCast;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
// Bulk Operations
/**
* Inserts all of the elements in the specified collection into this
* list at the specified position (optional operation). Shifts the
* element currently at that position (if any) and any subsequent
* elements to the right (increases their indices). The new elements
* will appear in this list in the order that they are returned by the
* specified collection's iterator. The behavior of this operation is
* undefined if the specified collection is modified while the
* operation is in progress. (Note that this will occur if the specified
* collection is this list, and it's nonempty.)
*
* <p>This implementation gets an iterator over the specified collection and
* a list iterator over this list pointing to the indexed element (with
* {@code listIterator(index)}). Then, it iterates over the specified
* collection, inserting the elements obtained from the iterator into this
* list, one at a time, using {@code ListIterator.add} followed by
* {@code ListIterator.next} (to skip over the added element).
*
* <p>Note that this implementation will throw an
* {@code UnsupportedOperationException} if the list iterator returned by
* the {@code listIterator} method does not implement the {@code add}
* operation.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
將指定集合中的所有元素插入此列表中的指定位置
*/
public boolean addAll(int index, Collection<? extends E> c) {
try {
boolean modified = false;
ListIterator<E> e1 = listIterator(index);
for (E e : c) {
e1.add(e);
modified = true;
}
return modified;
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
// Iterators
/**
* Returns an iterator over the elements in this list (in proper
* sequence).<p>
*
* This implementation merely returns a list iterator over the list.
*
* @return an iterator over the elements in this list (in proper sequence)
返回此列表中元素的迭代器(按適當順序)
*/
public Iterator<E> iterator() {
return listIterator();
}
/**
* Returns a list iterator over the elements in this list (in proper
* sequence).
*
* @param index index of first element to be returned from the list
* iterator (by a call to the {@code next} method)
* @return a list iterator over the elements in this list (in proper
* sequence)
* @throws IndexOutOfBoundsException {@inheritDoc}
返回此列表中的元素的列表迭代器(按適當順序)
*/
public abstract ListIterator<E> listIterator(int index);
}
Queue
public interface Queue<E> extends Collection<E> {
/**
* Inserts the specified element into this queue if it is possible to do so
* immediately without violating capacity restrictions, returning
* {@code true} upon success and throwing an {@code IllegalStateException}
* if no space is currently available.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
如果可以在不違反容量限制的情況下立即將指定的元素插入此隊列,則true在成功返回時返回指定的元素, 如果當前沒有可用空間,則拋出IllegalStateException。
*/
boolean add(E e);
/**
* Inserts the specified element into this queue if it is possible to do
* so immediately without violating capacity restrictions.
* When using a capacity-restricted queue, this method is generally
* preferable to {@link #add}, which can fail to insert an element only
* by throwing an exception.
*
* @param e the element to add
* @return {@code true} if the element was added to this queue, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
如果可以在不違反容量限制的情況下立即將指定的元素插入此隊列
*/
boolean offer(E e);
/**
* Retrieves and removes the head of this queue. This method differs
* from {@link #poll() poll()} only in that it throws an exception if
* this queue is empty.
*
* @return the head of this queue
* @throws NoSuchElementException if this queue is empty
檢索並刪除此隊列的頭。沒有元素是拋出異常
*/
E remove();
/**
* Retrieves and removes the head of this queue,
* or returns {@code null} if this queue is empty.
*
* @return the head of this queue, or {@code null} if this queue is empty
檢索並刪除此隊列的頭部,null如果此隊列爲空,則返回。
*/
E poll();
/**
* Retrieves, but does not remove, the head of this queue. This method
* differs from {@link #peek peek} only in that it throws an exception
* if this queue is empty.
*
* @return the head of this queue
* @throws NoSuchElementException if this queue is empty
檢索但不刪除此隊列的頭,沒有元素時,拋出異常
*/
E element();
/**
* Retrieves, but does not remove, the head of this queue,
* or returns {@code null} if this queue is empty.
*
* @return the head of this queue, or {@code null} if this queue is empty
檢索但不刪除此隊列的頭部,null如果此隊列爲空,則返回
*/
E peek();
}
隊列方法摘要
Deque
/**
雙向隊列
隊頭,隊尾,都可以插入刪除,繼承Queue
**/
public interface Deque<E> extends Queue<E> {
/**
* Inserts the specified element at the front of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* throwing an {@code IllegalStateException} if no space is currently
* available. When using a capacity-restricted deque, it is generally
* preferable to use method {@link #offerFirst}.
*
* @param e the element to add
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
插入一個元素到隊列前面
*/
void addFirst(E e);
/**
* Inserts the specified element at the end of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* throwing an {@code IllegalStateException} if no space is currently
* available. When using a capacity-restricted deque, it is generally
* preferable to use method {@link #offerLast}.
*
* <p>This method is equivalent to {@link #add}.
*
* @param e the element to add
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
插入一個元素到隊列後面
*/
void addLast(E e);
/**
* Inserts the specified element at the front of this deque unless it would
* violate capacity restrictions. When using a capacity-restricted deque,
* this method is generally preferable to the {@link #addFirst} method,
* which can fail to insert an element only by throwing an exception.
*
* @param e the element to add
* @return {@code true} if the element was added to this deque, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
插入一個元素到隊列前面,如果違反容量限制,就拋出異常
*/
boolean offerFirst(E e);
/**
* Inserts the specified element at the end of this deque unless it would
* violate capacity restrictions. When using a capacity-restricted deque,
* this method is generally preferable to the {@link #addLast} method,
* which can fail to insert an element only by throwing an exception.
*
* @param e the element to add
* @return {@code true} if the element was added to this deque, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
插入一個元素到隊列後面,如果違反容量限制,就拋出異常
*/
boolean offerLast(E e);
/**
* Retrieves and removes the first element of this deque. This method
* differs from {@link #pollFirst pollFirst} only in that it throws an
* exception if this deque is empty.
*
* @return the head of this deque
* @throws NoSuchElementException if this deque is empty
檢索並刪除此deque的第一個元素 如果隊列是空 拋出NoSuchElementException
*/
E removeFirst();
/**
* Retrieves and removes the last element of this deque. This method
* differs from {@link #pollLast pollLast} only in that it throws an
* exception if this deque is empty.
*
* @return the tail of this deque
* @throws NoSuchElementException if this deque is empty
檢索並刪除此deque的最後一個元素 如果隊列是空 拋出NoSuchElementException
*/
E removeLast();
/**
* Retrieves and removes the first element of this deque,
* or returns {@code null} if this deque is empty.
*
* @return the head of this deque, or {@code null} if this deque is empty
檢索並刪除此deque的第一個元素
*/
E pollFirst();
/**
* Retrieves and removes the last element of this deque,
* or returns {@code null} if this deque is empty.
*
* @return the tail of this deque, or {@code null} if this deque is empty
檢索並刪除此deque的最後一個元素
*/
E pollLast();
/**
* Retrieves, but does not remove, the first element of this deque.
*
* This method differs from {@link #peekFirst peekFirst} only in that it
* throws an exception if this deque is empty.
*
* @return the head of this deque
* @throws NoSuchElementException if this deque is empty
檢索並獲得此deque的第一個元素。如果隊列是空 拋出NoSuchElementException
*/
E getFirst();
/**
* Retrieves, but does not remove, the last element of this deque.
* This method differs from {@link #peekLast peekLast} only in that it
* throws an exception if this deque is empty.
*
* @return the tail of this deque
* @throws NoSuchElementException if this deque is empty
檢索並獲得此deque的最後一個元素。如果隊列是空 拋出NoSuchElementException
*/
E getLast();
/**
* Retrieves, but does not remove, the first element of this deque,
* or returns {@code null} if this deque is empty.
*
* @return the head of this deque, or {@code null} if this deque is empty
檢索並獲得此deque的第一個元素。
*/
E peekFirst();
/**
* Retrieves, but does not remove, the last element of this deque,
* or returns {@code null} if this deque is empty.
*
* @return the tail of this deque, or {@code null} if this deque is empty
檢索並獲得此deque的最後一個元素。
*/
E peekLast();
/**
* Removes the first occurrence of the specified element from this deque.
* If the deque does not contain the element, it is unchanged.
* More formally, removes the first element {@code e} such that
* {@code Objects.equals(o, e)} (if such an element exists).
* Returns {@code true} if this deque contained the specified element
* (or equivalently, if this deque changed as a result of the call).
*
* @param o element to be removed from this deque, if present
* @return {@code true} if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
* is incompatible with this deque
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
從此deque中刪除指定元素的第一個出現。
*/
boolean removeFirstOccurrence(Object o);
/**
* Removes the last occurrence of the specified element from this deque.
* If the deque does not contain the element, it is unchanged.
* More formally, removes the last element {@code e} such that
* {@code Objects.equals(o, e)} (if such an element exists).
* Returns {@code true} if this deque contained the specified element
* (or equivalently, if this deque changed as a result of the call).
*
* @param o element to be removed from this deque, if present
* @return {@code true} if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
* is incompatible with this deque
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
從此deque中刪除指定元素的最後一個出現
*/
boolean removeLastOccurrence(Object o);
// *** Queue methods ***
/**
* Inserts the specified element into the queue represented by this deque
* (in other words, at the tail of this deque) if it is possible to do so
* immediately without violating capacity restrictions, returning
* {@code true} upon success and throwing an
* {@code IllegalStateException} if no space is currently available.
* When using a capacity-restricted deque, it is generally preferable to
* use {@link #offer(Object) offer}.
*
* <p>This method is equivalent to {@link #addLast}.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
如果可以在不違反容量限制的情況下立即執行此操作,則將指定的元素插入此雙端隊列表示的隊列中(換句話說,在此雙端隊列的末尾),如果true成功則返回 ,IllegalStateException如果當前沒有可用空間,則拋出
*/
boolean add(E e);
/**
* Inserts the specified element into the queue represented by this deque
* (in other words, at the tail of this deque) if it is possible to do so
* immediately without violating capacity restrictions, returning
* {@code true} upon success and {@code false} if no space is currently
* available. When using a capacity-restricted deque, this method is
* generally preferable to the {@link #add} method, which can fail to
* insert an element only by throwing an exception.
*
* <p>This method is equivalent to {@link #offerLast}.
*
* @param e the element to add
* @return {@code true} if the element was added to this deque, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
如果可以在不違反容量限制的情況下立即執行此操作,則將指定的元素插入此雙端隊列表示的隊列中(換句話說,在此雙端隊列的末尾),如果true成功,並且false當前沒有可用空間,則將其插入 。
*/
boolean offer(E e);
/**
* Retrieves and removes the head of the queue represented by this deque
* (in other words, the first element of this deque).
* This method differs from {@link #poll() poll()} only in that it
* throws an exception if this deque is empty.
*
* <p>This method is equivalent to {@link #removeFirst()}.
*
* @return the head of the queue represented by this deque
* @throws NoSuchElementException if this deque is empty
檢索並刪除此雙端隊列代表的隊列的頭部,如果隊列爲空,拋出NoSuchElementException
*/
E remove();
/**
* Retrieves and removes the head of the queue represented by this deque
* (in other words, the first element of this deque), or returns
* {@code null} if this deque is empty.
*
* <p>This method is equivalent to {@link #pollFirst()}.
*
* @return the first element of this deque, or {@code null} if
* this deque is empty
檢索並刪除此雙端隊列表示的隊列的頭部
*/
E poll();
/**
* Retrieves, but does not remove, the head of the queue represented by
* this deque (in other words, the first element of this deque).
* This method differs from {@link #peek peek} only in that it throws an
* exception if this deque is empty.
*
* <p>This method is equivalent to {@link #getFirst()}.
*
* @return the head of the queue represented by this deque
* @throws NoSuchElementException if this deque is empty
檢索但不刪除此雙端隊列代表的隊列的頭,如果隊列爲空,拋出NoSuchElementException
*/
E element();
/**
* Retrieves, but does not remove, the head of the queue represented by
* this deque (in other words, the first element of this deque), or
* returns {@code null} if this deque is empty.
*
* <p>This method is equivalent to {@link #peekFirst()}.
*
* @return the head of the queue represented by this deque, or
* {@code null} if this deque is empty
檢索但不刪除此雙端隊列表示的隊列的頭(換句話說,此雙端隊列的第一個元素),null如果此雙端隊列爲空,則返回
*/
E peek();
/**
* Adds all of the elements in the specified collection at the end
* of this deque, as if by calling {@link #addLast} on each one,
* in the order that they are returned by the collection's iterator.
*
* <p>When using a capacity-restricted deque, it is generally preferable
* to call {@link #offer(Object) offer} separately on each element.
*
* <p>An exception encountered while trying to add an element may result
* in only some of the elements having been successfully added when
* the associated exception is thrown.
*
* @param c the elements to be inserted into this deque
* @return {@code true} if this deque changed as a result of the call
* @throws IllegalStateException if not all the elements can be added at
* this time due to insertion restrictions
* @throws ClassCastException if the class of an element of the specified
* collection prevents it from being added to this deque
* @throws NullPointerException if the specified collection contains a
* null element and this deque does not permit null elements,
* or if the specified collection is null
* @throws IllegalArgumentException if some property of an element of the
* specified collection prevents it from being added to this deque
在此雙端隊列的末尾添加指定集合中的所有元素,就像通過調用addLast(E)每個元素一樣,以集合的迭代器返回它們的順序
*/
boolean addAll(Collection<? extends E> c);
// *** Stack methods ***
/**
* Pushes an element onto the stack represented by this deque (in other
* words, at the head of this deque) if it is possible to do so
* immediately without violating capacity restrictions, throwing an
* {@code IllegalStateException} if no space is currently available.
*
* <p>This method is equivalent to {@link #addFirst}.
*
* @param e the element to push
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this deque
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* @throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this deque
如果有可能在不違反容量限制的情況下立即進行操作,則將一個元素推入此雙端隊列表示的堆棧上(換句話說,在此雙端隊列的頭部),如果IllegalStateException當前沒有可用空間,則拋出 。
*/
void push(E e);
/**
* Pops an element from the stack represented by this deque. In other
* words, removes and returns the first element of this deque.
*
* <p>This method is equivalent to {@link #removeFirst()}.
*
* @return the element at the front of this deque (which is the top
* of the stack represented by this deque)
* @throws NoSuchElementException if this deque is empty
從此雙端隊列表示的堆棧中彈出一個元素,如果隊列爲空,則拋出NoSuchElementException
*/
E pop();
// *** Collection methods ***
/**
* Removes the first occurrence of the specified element from this deque.
* If the deque does not contain the element, it is unchanged.
* More formally, removes the first element {@code e} such that
* {@code Objects.equals(o, e)} (if such an element exists).
* Returns {@code true} if this deque contained the specified element
* (or equivalently, if this deque changed as a result of the call).
*
* <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
*
* @param o element to be removed from this deque, if present
* @return {@code true} if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
* is incompatible with this deque
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
從此雙端隊列刪除指定元素的第一次出現
*/
boolean remove(Object o);
/**
* Returns {@code true} if this deque contains the specified element.
* More formally, returns {@code true} if and only if this deque contains
* at least one element {@code e} such that {@code Objects.equals(o, e)}.
*
* @param o element whose presence in this deque is to be tested
* @return {@code true} if this deque contains the specified element
* @throws ClassCastException if the class of the specified element
* is incompatible with this deque
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
* deque does not permit null elements
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
返回true此雙端隊列是否包含指定的元素。
*/
boolean contains(Object o);
/**
* Returns the number of elements in this deque.
*
* @return the number of elements in this deque
返回此雙端隊列中的元素數。
*/
int size();
/**
* Returns an iterator over the elements in this deque in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
* @return an iterator over the elements in this deque in proper sequence
以適當的順序返回此雙端隊列中的元素的迭代器
*/
Iterator<E> iterator();
/**
* Returns an iterator over the elements in this deque in reverse
* sequential order. The elements will be returned in order from
* last (tail) to first (head).
*
* @return an iterator over the elements in this deque in reverse
* sequence
以相反的順序返回此雙端隊列中的元素的迭代器
*/
Iterator<E> descendingIterator();
}
總結:
4.屬性
//元素個數
transient int size = 0;
/**
* Pointer to first node.
指向第一個節點的指針
*/
transient Node<E> first;
/**
* Pointer to last node.
指向最後一個節點的指針
*/
transient Node<E> last;
5.構造函數
/**
* Constructs an empty list.
*/
public LinkedList() {
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
6.內部結構
LinkedList內部是一個雙端鏈表的結構,結構如下圖:
可以看上面的四個元素,分別就是四個Node對象,可以看到node1所指向的prev上一個節點是空也就是沒有上節點,node4所指向的next節點爲空也就是沒有下一個節點
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;
}
}
7.添加元素
1)add方法(有6個人方法)
add(E):
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
//指向鏈表尾部
final Node<E> l = last;
//以尾部爲前驅節點創建一個新節點
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;//將鏈表尾部指向新節點
if (l == null)//如果鏈表爲空,那麼該節點即是頭,也是尾
first = newNode;
else //如果鏈表不爲空,那麼將該節點作爲原鏈表尾的後繼節點
l.next = newNode;
size++;// 節點數加1
modCount++;
}
add(int,E)
public void add(int index, E element) {
checkPositionIndex(index);//校驗索引是否合法
if (index == size)//添加到鏈表尾部
linkLast(element);
else //添加到鏈表中間
linkBefore(element, node(index));
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size; //判斷索引是否合法
}
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;//將pred設爲插入節點的上一個節點
//將新節點的上引用設爲pred,下引用設爲succ
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;//succ的上一個節點設置newNode
if (pred == null)//新節點的話就是頭結點
first = newNode;
else
pred.next = newNode;// 插入節點的上一個節點的下一個節點引用設爲新節點
size++;//同上
modCount++;
}
addAll(Collection<? extends E>)
//將集合插入到鏈表尾部,即開始索引位置爲size
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
//將集合從指定位置開始插入
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);//檢查index範圍
Object[] a = c.toArray();//得到集合數據
int numNew = a.length;
if (numNew == 0)
return false;
Node<E> pred, succ;
//如果插入位置爲尾部,前驅節點爲last,後繼節點爲null
if (index == size) {
succ = null;
pred = last;
}
//否則,調用node方法得到後繼節點,在得到前驅節點
else {
succ = node(index);
pred = succ.prev;
}
//遍歷數據將數據插入
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
//創建新節點
Node<E> newNode = new Node<>(pred, e, null);
//插入位置爲鏈表頭部
if (pred == null)
first = newNode;
else
pred.next = newNode;//將新節點插入到pred的後繼節點
pred = newNode;//pred重新賦值,以便於下次循環加入
}
//如果插入的位置在尾部,重置last節點
if (succ == null) {
last = pred;
}
//否則,將插入的鏈表和之前的鏈表連接起來
else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
從上面的代碼可以看到,addAll方法主要分爲4步:
1. 檢查index索引範圍
2. 得到集合數據
3. 得到插入位置的前驅和後繼節點
4. 遍歷數據,將數據插入到指定位置
addFirst
//將元素添加到鏈表頭部
public void addFirst(E e) {
linkFirst(e);
}
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
//將新節點設爲頭節點
first = newNode;
//如果鏈表爲空,last節點也指向該節點
if (f == null)
last = newNode;
else
f.prev = newNode; //將原先的頭結點指向新節點
size++; //節點數加1
modCount++;//記錄修改次數
}
addLast
//將元素添加到列表尾部,與add()方法一樣
public void addLast(E e) {
linkLast(e);
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
offer(E e)方法
//將數據添加到鏈表尾部,其內部調用了add(E e)方法
public boolean offer(E e) {
return add(e);
}
offerLast()與addLast()的區別和offerFirst()和addFirst()的區別一樣,所以這兒就不多說了。其實質是一樣的
總結:
將數據插入到鏈表尾部
- boolean add(E e):
- void addLast(E e)
- boolean offerLast(E e)
- 將數據插入到鏈表頭部
- void addFirst(E e)
- boolean offerFirst(E e)
- 將數據插入到指定索引位置
- boolean add(int index,E e)
8 檢索操作
根據位置取數據
get(int)
//根據指定索引返回數據,如果索引越界,那麼會拋出異常
public E get(int index) {
//檢查邊界
checkElementIndex(index);
return node(index).item;
}
//獲取頭節點數據
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
//獲取頭節點數據
public E element() {
return getFirst();
}
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
public E element() {
return getFirst();
}
LinkedList中有多種方法可以獲得頭節點的數據,實現大同小異,區別在於對鏈表爲空時的處理,是拋出異常還是返回null。主要方法有getFirst()、element()、peek()、peekFirst()、方法。其中getFirst()和element()方法將會在鏈表爲空時,拋出異常
獲取尾節點數據
//獲取尾節點數據
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
}
getLast()方法在鏈表爲空時,會拋出NoSuchElementException,而peekLast()則不會,只是會返回null
根據對象得到索引
//返回第一個匹配的索引
public int indexOf(Object o) {
int index = 0;
if (o == null) {
//從頭往後遍歷
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//從頭往後遍歷
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
//LinkedList可以包含null元素,遍歷方式都是從前往後,一旦匹配了,就返回索引
//返回最後一個匹配的索引
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
//從後往前遍歷
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
//從後往前遍歷
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
檢查鏈表是否包含某對象
//檢查對象o是否存在於鏈表中
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//contains()方法調用了indexOf()方法,只要返回結果不是-1,那就說明該對象存在於鏈表中
檢索操作總結
檢索操作分爲按照位置得到對象以及按照對象得到位置兩種方式,其中按照對象得到位置的方法有indexOf()和lastIndexOf();按照位置得到對象有如下方法:
- 根據任意位置得到數據的get(int index)方法,當index越界會拋出異常
- 獲得頭節點數據
- getFirst()和element()方法在鏈表爲空時會拋出NoSuchElementException
- peek()和peekFirst()方法在鏈表爲空時會返回null
- 獲得尾節點數據
- getLast()在鏈表爲空時會拋出NoSuchElementException
- peekLast()在鏈表爲空時會返回null
9 刪除操作
刪除指定對象
remove
public E remove() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
//next爲頭結點的下一個節點
final Node<E> next = f.next;
//將節點的元素以及引用都設爲null,便於垃圾回收
f.item = null;
f.next = null; // help GC
//修改頭結點爲第二個節點
first = next;
//如果第二個節點爲空(當前鏈表只存在第一個元素)
if (next == null)
last = null;
else
//將第二個節點的上一個引用置爲null
next.prev = null;
size--;
modCount++;
return element;
}
remove(int)
//刪除指定節點
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
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;
//刪除前驅指針
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;
}
remove(object)
public boolean remove(Object o) {
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;
}
刪除頭節點
刪除頭節點的對象的方法有很多,包括remove()、removeFirst()、pop()、poll()、pollFirst(),其中前三個方法在鏈表爲空時將拋出NoSuchElementException,後兩個方法在鏈表爲空時將返回null。代碼和上面基本類似,不在做介紹
刪除尾節點對象
刪除尾節點的對象的方法有removeLast()和pollLast()。removeLast的實現如下:
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
可以看到removeLast()在鏈表爲空時將拋出NoSuchElementException。而pollLast()方法則不會,如下:
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
}
可以看到pollLast()在鏈表爲空時會返回null,而不是拋出異常。
刪除操作總結
刪除操作由很多種方法,有:
- 按照指定對象刪除:boolean remove(Object o),一次只會刪除一個匹配的對象
- 按照指定位置刪除
- 刪除任意位置的對象:E remove(int index),當index越界時會拋出異常
- 刪除頭節點位置的對象
- 在鏈表爲空時拋出異常:E remove()、E removeFirst()、E pop()
- 在鏈表爲空時返回null:E poll()、E pollFirst()
- 刪除尾節點位置的對象
- 在鏈表爲空時拋出異常:E removeLast()
- 在鏈表爲空時返回null:E pollLast()
10迭代操作
listIterator()
//listIterator實際上是ListItr這個類,下面介紹這個類
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private Node<E> lastReturned;
private Node<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
// assert isPositionIndex(index);
next = (index == size) ? null : node(index);
nextIndex = index;
}
public boolean hasNext() {
return nextIndex < size;
}
//獲取下一個節點
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
//獲取前一個節點,將next節點前移
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
在ListIterator的構造器中,得到了當前位置的節點,就是變量next。next()方法返回當前節點的值並將next指向其後繼節點,previous()方法返回當前節點的前一個節點的值並將next節點指向其前驅節點。由於Node是一個雙端節點,所以這兒用了一個節點就可以實現從前向後迭代和從後向前迭代。另外在ListIterator初始時,exceptedModCount保存了當前的modCount,如果在迭代期間,有操作改變了鏈表的底層結構,那麼再操作迭代器的方法時將會拋出ConcurrentModificationException
總結
LinkedList是基於雙端鏈表的List,其內部的實現源於對鏈表的操作,所以適用於頻繁增加、刪除的情況;該類不是線程安全的;另外,由於LinkedList實現了Queue接口,所以LinkedList不止有隊列的接口,還有棧的接口,可以使用LinkedList作爲隊列和棧的實現。