java集合系列——List集合之LinkedList介绍(三)

LinkedList是基于链表实现的,从源码可以看出是一个双向链表。除了当做链表使用外,它也可以被当作堆栈、队列或双端队列进行操作。不是线程安全的,继承AbstractSequentialList实现List、Deque、Cloneable、Serializable。

大家好,又见面了,我是全栈君。

1. LinkedList的简介 JDK1.7.0_79版本

LinkedList是基于链表实现的,从源码可以看出是一个双向链表。除了当做链表使用外,它也可以被当作堆栈、队列或双端队列进行操作。不是线程安全的,继承AbstractSequentialList实现List、Deque、Cloneable、Serializable。

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • LinkedList继承AbstractSequentialList,AbstractSequentialList 实现了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)这些函数。这些接口都是随机访问List的。

  • LinkedList 实现 List 接口,能对它进行队列操作。

  • LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。

  • LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。

  • LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。

    2. LinkedList的继承关系
    LinkedList API

java.lang.Object 
    java.util.AbstractCollection<E> 
        java.util.AbstractList<E> 
        java.util.AbstractSequentialList<E> 
            java.util.LinkedList<E> 

Type Parameters:
E - the type of elements held in this collection
All Implemented Interfaces: 
Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E> 

这里写图片描述

3.LinkedList的API

boolean add(E e) 
     将指定元素添加到此列表的结尾。
 void   add(int index, E element) 
     在此列表中指定的位置插入指定的元素。
 boolean    addAll(Collection<? extends E> c) 
     添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。
 boolean    addAll(int index, Collection<? extends E> c) 
      将指定 collection 中的所有元素从指定位置开始插入此列表。
 void   addFirst(E e) 
      将指定元素插入此列表的开头。
 void   addLast(E e) 
     将指定元素添加到此列表的结尾。
 void   clear() 
    从此列表中移除所有元素。
 Object clone() 
     返回此 LinkedList 的浅表副本。
 boolean    contains(Object o) 
     如果此列表包含指定元素,则返回 true。
 Iterator<E>    descendingIterator() 
     返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。
 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() 
    获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
 E  peekLast() 
   获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
 E  poll() 
    获取并移除此列表的头(第一个元素)
 E  pollFirst() 
     获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
 E  pollLast() 
     获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
 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() 
    返回此列表的元素数。
 Object[]   toArray() 
    返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。
<T> T[] toArray(T[] a) 
     返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。

4.LinkedList源码分析

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/** * Pointer to first node. --指向第一个节点的指针。 * Invariant: (first == null && last == null) || * 不变条件 (first.prev == null && first.item != null) */
transient Node<E> first;
/** * Pointer to last node. --指向最后一个节点的指针。 * Invariant: (first == null && last == null) || * 不变条件 (last.next == null && last.item != null) */
transient Node<E> last;
/** * 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 * c其元素将被放置到此列表中的集合 * @throws NullPointerException if the specified collection is null */
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
/** * Links e as first element. * e 作为第一个链接,私有方法,在addFirst(E e)方法中使用! */
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
/* /** * 链表节点的构造函数。 * 参数说明: * element —— 节点所包含的数据 * next —— 下一个节点 * prev —— 上一个节点 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } */
}
/** * Links e as last element. * e 作为最后一个链接,私有方法,在addLast(E 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++;
}
/** * Inserts element e before non-null Node succ. * 在非空节点succ之前插入元素e。 */
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
/** * Unlinks non-null first node f. * 取消链接非空的第一个节点f。 * 私有方法,在removeFirst()方法中使用! */
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
/** * Unlinks non-null last node l. * 取消链接非空的最后一个节点l。 * 私有方法,在removeLast()方法中使用! */
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
/** * Unlinks non-null node x. * 取消链接非空节点x。 * 在remove中使用 */
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;
}
/** * Returns the first element in this list. * 返回此列表中的第一个元素。 * @return the first element in this list * @throws NoSuchElementException if this list is empty */
public E getFirst() {
final Node<E> f = first; //第一个元素
if (f == null)
throw new NoSuchElementException();
return f.item;
}
/** * Returns the last element in this list. * 返回此列表中的最后一个元素。 * @return the last element in this list * @throws NoSuchElementException if this list is empty */
public E getLast() {
final Node<E> l = last;//最后一个元素
if (l == null)
throw new NoSuchElementException();
return l.item;
}
/** * Removes and returns the first element from this list. * 删除并返回此列表中的第一个元素。 * @return the first element from this list * @throws NoSuchElementException if this list is empty */
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
/** * Removes and returns the last element from this list. * 删除并返回此列表中的最后一个元素。 * @return the last element from this list * @throws NoSuchElementException if this list is empty */
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
/** * Inserts the specified element at the beginning of this list. * 在此列表的开头插入指定的元素。 * @param e the element to add */
public void addFirst(E e) {
linkFirst(e);
}
/** * Appends the specified element to the end of this list. * 将指定的元素追加到此列表的末尾。 * <p>This method is equivalent to { 
@link #add}. * * @param e the element to add */
public void addLast(E e) {
linkLast(e);
}
/** * *如果此列表包含指定的元素,则返回true。 更正式地,当且仅当这个列表包含至少一个元素e使得 *(o == null?e == *null:o.equals(e))时,返回true。 * * @param o element whose presence in this list is to be tested * @return { 
@code true} if this list contains the specified element */
public boolean contains(Object o) {
return indexOf(o) != -1;  //使用indexOf 方法
}
/** * Returns the number of elements in this list. * 返回此列表中的元素数。 * @return the number of elements in this list */
public int size() {
return size;
}
/** * Appends the specified element to the end of this list. * 将指定的元素追加到此列表的末尾。 * <p>This method is equivalent to { 
@link #addLast}. * 此方法等效与addLast方法 * @param e element to be appended to this list * @return { 
@code true} (as specified by { 
@link Collection#add}) */
public boolean add(E e) {
linkLast(e);
return true;
}
/** * *从列表中删除指定元素的第一次出现(如果存在)。 如果此列表不包含元素,则不会更改。 * *更正式地,删除具有最低索引i的元素,使得(如果这样的元素存在)(o == null?get(i)== null:o.equals(get(i)))。 *如果此列表包含指定的元素(或等效地,如果此列表作为调用的结果更改),则返回true。 * * @param o element to be removed from this list, if present * @return { 
@code true} if this list contained the specified element */
public boolean remove(Object o) {
if (o == null) { //从头开始遍历整个列表,若列表中有null的元素,则移除!(第一次出现)
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
//从头开始遍历整个列表,若列表中有 o 的元素,则移除!(第一次出现)
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
/** *将指定集合中的所有元素以指定集合的迭代器返回的顺序追加到此列表的末尾。 * * @param c collection containing elements to be added to this list * @return { 
@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
/** *在指定的位置,将指定集合中的所有元素以指定集合的迭代器返回的顺序追加到此列表的末尾。 * * @param index index at which to insert the first element * from the specified collection * @param c collection containing elements to be added to this list * @return { 
@code true} if this list changed as a result of the call * @throws IndexOutOfBoundsException { 
@inheritDoc} * @throws NullPointerException if the specified collection is null */
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index); //检查索引位置是否有效 index >= 0 && index <= size 返回true。
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} 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 = newNode;
}
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
/** * Removes all of the elements from this list. * The list will be empty after this call returns. *从此列表中删除所有元素。 此调用返回后,列表将为空。 */
public void clear() {
// Clearing all of the links between nodes is "unnecessary", but:
// - helps a generational GC if the discarded nodes inhabit
// more than one generation
// - is sure to free memory even if there is a reachable Iterator
for (Node<E> x = first; x != null; ) {
Node<E> next = x.next;
x.item = null; //设置为null ,等待gc回收
x.next = null; //设置为null ,等待gc回收
x.prev = null; //设置为null ,等待gc回收
x = next;
}
first = last = null;
size = 0; //设置列表的大小为 0;
modCount++;
}
// Positional Access Operations
// 定位访问操作
/** * Returns the element at the specified position in this list. * 返回此lis中指定位置的元素 * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException { 
@inheritDoc} */
public E get(int index) {
checkElementIndex(index); //检查索引位置是否有效 index >= 0 && index <= size 返回true。
return node(index).item;  //返回指定元素索引处的(非空)节点的元素(data)
}
/** * Replaces the element at the specified position in this list with the * specified element. * 用指定的元素替换此列表中指定位置处的元素。返回元素的旧值 * @param index index of the element to replace * @param element element to be stored at the specified position * @return the element previously at the specified position * @throws IndexOutOfBoundsException { 
@inheritDoc} */
public E set(int index, E element) {
checkElementIndex(index); //检查索引位置是否有效 index >= 0 && index <= size 返回true。
Node<E> x = node(index); //返回指定元素索引处的(非空)节点。
//替换操作
E oldVal = x.item;
x.item = element;
return oldVal;
}
/** * 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) {
checkPositionIndex(index);
if (index == size) //索引位置等于 列表的大小,则在链表后面添加元素
linkLast(element);
else
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));  // node(index)获取指定索引的节点。unlink()移除节点数据,并将任何后续元素向左移
}
/** * Tells if the argument is the index of an existing element. * 告诉参数是否是现有元素的索引。 */
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
/** * Tells if the argument is the index of a valid position for an * iterator or an add operation. * 告诉参数是迭代器的有效位置的索引还是添加操作。 */
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
/** * Constructs an IndexOutOfBoundsException detail message. * 构造一个IndexOutOfBoundsException详细消息。 */
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/** * Returns the (non-null) Node at the specified element index. * 返回指定元素索引处的(非空)节点。 */
Node<E> node(int index) {
// assert isElementIndex(index);
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;
}
}
// Search Operations
// 搜索操作
/** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index { 
@code i} such that * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>, * or -1 if there is no such index. * * 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 * 更正式地,返回最低索引i,使得(o == null?get(i)== null:o.equals(get(i))), * 或-1,如果没有这样的索引。 * * @param o element to search for * @return the index of the first occurrence of the specified element in * this list, or -1 if this list does not contain the element */
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;
}
/** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index { 
@code i} such that * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>, * or -1 if there is no such index. * * 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 * 更正式地,返回最高索引i,使得(o == null?get(i)== null:o.equals(get(i))), * 或-1如果没有这样的索引。 * * @param o element to search for * @return the index of the last occurrence of the specified element in * this list, or -1 if this list does not contain the element */
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;
}
// Queue operations.
// 队列操作。
/** * 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 * 返回 此列表的头部,或null(如果此列表为空) * @since 1.5 */
public E peek() {   
final Node<E> f = first;
return (f == null) ? null : f.item;
}
/** * Retrieves, but does not remove, the head (first element) of this list. * 检索,但不删除此列表的头(第一个元素) * @return the head of this list 返回:这个列表的头 * @throws NoSuchElementException if this list is empty * @since 1.5 */
public E element() {
return getFirst();
}
/** * Retrieves and removes the head (first element) of this list. * 检索并删除此列表的头(第一个元素)。 * @return the head of this list, or { 
@code null} if this list is empty * 返回 : 此列表的头部,或 null(如果此列表为空) * @since 1.5 */
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
/** * Retrieves and removes the head (first element) of this list. * 检索并删除此列表的头(第一个元素)。 * @return the head of this list 返回:这个列表的头 * @throws NoSuchElementException if this list is empty * @since 1.5 */
public E remove() {
return removeFirst();
}
/** * 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);
}
// Deque operations
// Deque操作
/** * 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. * 检索但不删除此列表的第一个元素,如果此列表为空,则返回null * @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. * 检索但不删除此列表的最后一个元素,如果此列表为空,则返回null * @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. * * 检索并删除此列表的第一个元素,如果此列表为空,则返回null * * @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. * *检索并删除此列表的最后一个元素,如果此列表为空,则返回null * * @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);
}
/** * Pushes an element onto the stack represented by this list. In other * words, inserts the element at the front of this list. * 将元素推送到此列表所表示的堆栈。 * 换句话说,将元素插入此列表的前面。(栈push 元素存放在栈顶) * <p>This method is equivalent to { 
@link #addFirst}. * 这个方法等效于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()}. * 此方法 相当于 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();
}
/** *删除此列表中指定元素的第一次出现(从头到尾遍历列表时)。 *如果列表不包含元素,则不会更改。 * @param o element to be removed from this list, if present * @return { 
@code true} if the list contained the specified element * @since 1.6 */
public boolean removeFirstOccurrence(Object o) {
return remove(o); //从链表头部开始遍历,找到元素移除
}
/** * 删除此列表中指定元素的第一次出现(从头到尾遍历列表时)。 * 如果列表不包含元素,则不会更改。 * * @param o element to be removed from this list, if present * @return { 
@code true} if the list contained the specified element * @since 1.6 */
//从链表尾部开始遍历,找到元素移除
public boolean removeLastOccurrence(Object o) {
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
/** *返回此列表中的元素(按正确顺序)的列表迭代器,从列表中指定的位置开始。 * 服从List.listIterator(int)的约定。 */
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> { 

//不去分析这个方法中的内容,有需要的请自行分析
}
private static class Node<E> { 

E item; // 当前节点所包含的值 
Node<E> next;// 下一个节点 
Node<E> prev; // 上一个节点 
/** * 链表节点的构造函数。 * 参数说明: * element —— 节点所包含的数据 * next —— 下一个节点 * previous —— 上一个节点 */   
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
/** * @since 1.6 */
public Iterator<E> descendingIterator() {
return new DescendingIterator();
}
/** * Adapter to provide descending iterators via ListItr.previous * 适配器通过ListItr.previous提供降序迭代器 */
private class DescendingIterator implements Iterator<E> { 

private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}
/** * Returns a shallow copy of this { 
@code LinkedList}. (The elements * themselves are not cloned.) * 返回此链接列表的浅拷贝。 (元素本身未克隆。) * @return a shallow copy of this { 
@code LinkedList} instance */
public Object clone() {
LinkedList<E> clone = superClone();
// Put clone into "virgin" state
clone.first = clone.last = null;
clone.size = 0;
clone.modCount = 0;
// Initialize clone with our elements
for (Node<E> x = first; x != null; x = x.next)
clone.add(x.item);
return clone;
}
/** *以正确的顺序返回包含此列表中所有元素的数组(从第一个元素到最后一个元素)。 */
public Object[] toArray() {
Object[] result = new Object[size];
int i = 0;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
return result;
}
/** *返回一个包含正确顺序(从第一个元素到最后一个元素)的列表中所有元素的数组。 */
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
if (a.length > size)
a[size] = null;
return a;
}
private static final long serialVersionUID = 876323262645176354L;
/** * Saves the state of this { 
@code LinkedList} instance to a stream * (that is, serializes it). * * 将LinkedList实例的状态保存到流(即,序列化它)。 * */
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
// Write out size
s.writeInt(size);
// Write out all elements in the proper order.
for (Node<E> x = first; x != null; x = x.next)
s.writeObject(x.item);
}
/** * Reconstitutes this { 
@code LinkedList} instance from a stream * (that is, deserializes it). * 从流重构 LinkedList 实例(即,反序列化它) */
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
// Read in size
int size = s.readInt();
// Read in all elements in the proper order.
for (int i = 0; i < size; i++)
linkLast((E)s.readObject());
}
}

5.总结

1:LinkedList的实现是基于双向循环链表,实现的 List和Deque 接口。实现所有可选的列表操作,并允许所有元素(包括null)。

2:LinkedList是非线程安全的,只在单线程下适合使用。

3:这个类的iterator和返回的迭代器listIterator方法是fail-fast ,要注意ConcurrentModificationException 。

4:LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。

5:在查找和删除某元素时,都分为该元素为null和不为null两种情况来处理,LinkedList中允许元素为null。

6:由于是基于列表的,LinkedList的没有扩容方法!默认加入元素是尾部自动扩容!

7:LinkedList还实现了栈和队列的操作方法,因此也可以作为栈、队列和双端队列来使用,如peek 、push、pop等方法。

8:LinkedList是基于链表实现的,因此插入删除效率高,查找效率低!(因为查找需要遍历整个链表)

9:1.6 使用的是Entry存储
// 双向链表的节点所对应的数据结构。 
// 包含3部分:上一节点,下一节点,当前节点值。 
private static class Entry<E> { 
    
E element;     // 当前节点所包含的值 
Entry<E> next;    // 下一个节点 
Entry<E> previous;   // 上一个节点 
/** * 链表节点的构造函数。 * 参数说明: * element —— 节点所包含的数据 * next —— 下一个节点 * previous —— 上一个节点 */   
Entry(E element, Entry<E> next, Entry<E> previous) {    
this.element = element;    
this.next = next;    
this.previous = previous;    
}    
}    
1.7使用的是Node存储
// 双向链表的节点所对应的数据结构。 
// 包含3部分:上一节点,下一节点,当前节点值。 
private static class Node<E> { 

E item; // 当前节点所包含的值 
Node<E> next;// 下一个节点 
Node<E> prev; // 上一个节点 
/** * 链表节点的构造函数。 * 参数说明: * element —— 节点所包含的数据 * next —— 下一个节点 * previous —— 上一个节点 */   
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

java集合系列——java集合概述(一)
java集合系列——List集合之ArrayList介绍(二)
java集合系列——List集合之LinkedList介绍(三)
java集合系列——List集合之Vector介绍(四)
java集合系列——List集合之Stack介绍(五)
java集合系列——List集合总结(六)
java集合系列——Map介绍(七)
java集合系列——Map之HashMap介绍(八)
java集合系列——Map之TreeMap介绍(九)
java集合系列——Set之HashSet和TreeSet介绍(十)



如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页http://blog.csdn.net/u010648555

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/121186.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • C++在stack的deque实现

    C++在stack的deque实现

  • paddle深度学习基础之训练调试与优化

    paddle深度学习基础之训练调试与优化上一节咱们讨论了四种不同的优化算法,这一节,咱们讨论训练过程中的优化问题。本次代码修改模型全是在卷积神经网络

  • python文本框事件_文本框事件

    python文本框事件_文本框事件1、文本框焦点问题onBlur:当失去输入焦点后产生该事件onFocus:当输入获得焦点后,产生该文件Onchange:当文字值改变时,产生该事件OnseleCT:当文字加亮后,产生该文件onkeyup:每改变,就产生该文件onfocus=”if(value==’文本框里的字’){value=”}”onblur=”if(value==”){value=’文本框里的字’}”>点击时文字…

    2022年10月22日
  • ubuntu 20.04中文输入法安装

    ubuntu 20.04中文输入法安装sudoapt-getinstallfcitx-googlepinyin

  • 海量数据查询方案mysql_Mysql海量数据存储和解决方案之二—-Mysql分表查询海量数据…[通俗易懂]

    关键词:分库分表,路由机制,跨区查询,MySQL数据变更,分表数据查询管理器与线程技术的结合,Cache前面已经讲过Mysql实现海量海量数据存储查询时,主要有几个关键点,分表,分库,集群,M-S,负载均衡。其中分库分表是很重要的一点。分库是如何将海量的Mysql数据放到不同的服务器中,分表则是在分库基础上对数据现进行逻辑上的划分。数据划分可有多种方式,找到一个主键后,可以按号段分,也可以Has…

  • ziplist、quicklist、listpack源码设计解读

    从ziplist到quicklist,再到listpack的启发介绍Redis优化设计数据结构来提升内存利用率的时候,提到可以使用压缩列表(ziplist)来保存数据。所以现在你应该也知道,ziplist的最大特点,就是它被设计成一种内存紧凑型的数据结构,占用一块连续的内存空间,以达到节省内存的目的。但是,在计算机系统中,任何一个设计都是有利有弊的。对于ziplist来说,这个道理同样成立。虽然ziplist节省了内存开销,可它也存在两个设计代价:一是不能保存过多的元素,否则访问性能会

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号