美文网首页
JDK源码 -- LinkedList

JDK源码 -- LinkedList

作者: TomyZhang | 来源:发表于2019-08-13 09:36 被阅读0次

一、概念

类定义:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • 继承了AbstractSequentialList抽象类,实现了List接口,拥有一组List通用的操作。
  • 实现了Deque接口,可当做双端队列使用。
  • 实现了Cloneable接口,可进行浅层次拷贝。
  • 实现了Serializable接口,可进行序列化。

特点:

  • 长于在List中间插入和删除元素。
  • 随机访问元素较慢。

二、使用

//TestLinkedList
public class TestLinkedList {
    private static final String TAG = "TestLinkedList";
    private LinkedList<String> list = new LinkedList<>();

    public void testAdd() {
        list.add("a");
        list.add("b");
        list.add("c");
        Log.d(TAG, "zwm, add list: " + list);
    }

    public void testAddFirst() {
        list.addFirst("first");
        Log.d(TAG, "zwm, addFirst list: " + list);
    }

    public void testAddLast() {
        list.addLast("last");
        Log.d(TAG, "zwm, addLast list: " + list);
    }

    public void testAdd2() {
        list.add(0, "ii");
        list.add(1, "jj");
        list.add(2, "kk");
        Log.d(TAG, "zwm, add index list: " + list);
    }

    public void testAddAll() {
        LinkedList<String> temp = new LinkedList<>();
        temp.add("lll");
        temp.add("mmm");
        temp.add("nnn");
        list.addAll(temp);
        Log.d(TAG, "zwm, addAll list: " + list);
    }

    public void testAddAll2() {
        LinkedList<String> temp = new LinkedList<>();
        temp.add("xxxx");
        temp.add("zzzz");
        temp.add("yyyy");
        temp.add("zzzz");
        list.addAll(0, temp);
        Log.d(TAG, "zwm, addAll index list: " + list);
    }

    public void testGet() {
        Log.d(TAG, "zwm, get index 2: " + list.get(2));
    }

    public void testGetFirst() {
        Log.d(TAG, "zwm, getFirst: " + list.getFirst());
    }

    public void testGetLast() {
        Log.d(TAG, "zwm, getLast: " + list.getLast());
    }

    public void testIndexOf() {
        Log.d(TAG, "zwm, indexOf zzzz: " + list.indexOf("zzzz"));
    }

    public void testLastIndexOf() {
        Log.d(TAG, "zwm, lastIndexOf zzzz: " + list.lastIndexOf("zzzz"));
    }

    public void testClone() {
        LinkedList<String> cloneList = (LinkedList)list.clone();
        Log.d(TAG, "zwm, list.equals(cloneList): " + list.equals(cloneList));
        Log.d(TAG, "zwm, list==cloneList: " + (list==cloneList));
    }

    public void testContains() {
        Log.d(TAG, "zwm, contains zzzz: " + list.contains("zzzz"));
    }

    public void testContainsAll() {
        LinkedList<String> temp = new LinkedList<>();
        temp.add("xxxx");
        temp.add("yyyy");
        temp.add("zzzz");
        Log.d(TAG, "zwm, containsAll: " + list.containsAll(temp));
    }

    public void testSize() {
        Log.d(TAG, "zwm, size: " + list.size());
    }

    public void testClear() {
        list.clear();
        Log.d(TAG, "zwm, clear list: " + list);
    }

    public void testEmpty() {
        Log.d(TAG, "zwm, isEmpty: " + list.isEmpty());
    }

    public void testIterator() {
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            Log.d(TAG, "zwm, iterator item: " + iterator.next());
        }
    }

    public void testIterator2() {
        ListIterator<String> iterator = list.listIterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            Log.d(TAG, "zwm, listIterator item: " + item);
            if(TextUtils.equals(item, "b")) {
                Log.d(TAG, "zwm, remove b");
                iterator.remove();
            } else if(TextUtils.equals(item, "c")) {
                Log.d(TAG, "zwm, update c to x");
                iterator.set("x");
            }
        }
        Log.d(TAG, "zwm, listIterator list: " + list);
        Log.d(TAG, "zwm, next index: " + iterator.nextIndex());
        Log.d(TAG, "zwm, previous index: " + iterator.previousIndex());
        while(iterator.hasPrevious()) {
            String item = iterator.previous();
            Log.d(TAG, "zwm, listIterator item: " + item);
        }
    }

    public void testIterator3() {
        ListIterator<String> iterator = list.listIterator(2);
        while (iterator.hasNext()) {
            String item = iterator.next();
            Log.d(TAG, "zwm, listIterator index item: " + item);
        }
    }

    public void testDescendingIterator() {
        Iterator<String> descendingIterator = list.descendingIterator();
        while (descendingIterator.hasNext()) {
            Log.d(TAG, "zwm, descendingIterator item: " + descendingIterator.next());
        }
    }

    public void testRemove() {
        Log.d(TAG, "zwm, remove a: " + list.remove("a"));
        Log.d(TAG, "zwm, remove list: " + list);
    }

    public void testRemove2() {
        Log.d(TAG, "zwm, remove index 3: " + list.remove(3));
        Log.d(TAG, "zwm, remove index list: " + list);
    }

    public void testRemove3() {
        Log.d(TAG, "zwm, remove: " + list.remove());
        Log.d(TAG, "zwm, remove list: " + list);
    }

    public void testRemoveFirst() {
        list.removeFirst();
        Log.d(TAG, "zwm, removeFirst list: " + list);
    }

    public void testRemoveLast() {
        list.removeLast();
        Log.d(TAG, "zwm, removeLast list: " + list);
    }

    public void testRemoveAll() {
        LinkedList<String> temp = new LinkedList<>();
        temp.add("a");
        temp.add("b");
        Log.d(TAG, "zwm, removeAll: " + list.removeAll(temp));
        Log.d(TAG, "zwm, removeAll list: " + list);
    }

    public void testElement() {
        Log.d(TAG, "zwm, element: " + list.element());
        Log.d(TAG, "zwm, element list: " + list);
    }

    public void testRetainAll() {
        LinkedList<String> temp = new LinkedList<>();
        temp.add("a");
        temp.add("b");
        temp.add("c");
        Log.d(TAG, "zwm, retainAll: " + list.retainAll(temp));
        Log.d(TAG, "zwm, retainAll list: " + list);
    }

    public void testSet() {
        list.set(0, "sss");
        Log.d(TAG, "zwm, set list: " + list);
    }

    public void testSubList() {
        //以下注释语句会抛出异常java.lang.ClassCastException: java.util.SubList cannot be cast to java.util.LinkedList
        //LinkedList<String> subList = (LinkedList<String>)list.subList(1, 2);
        List<String> subList = list.subList(1, 3);
        Log.d(TAG, "zwm, subList: " + subList);
    }

    public void testToArray() {
        Object[] arrays = list.toArray();
        for(Object item : arrays) {
            Log.d(TAG, "zwm, toArray item: " + item);
        }
    }

    public void testToArray2() {
        String[] param = new String[list.size()];
        String[] result = list.toArray(param);
        for(String item : param) {
            Log.d(TAG, "zwm, toArray T param item: " + item);
        }
        for(String item : result) {
            Log.d(TAG, "zwm, toArray T result item: " + item);
        }
    }

    //LinkedList实现栈 start
    public void testPushStack() {
        list.push("AAAA");
        list.push("BBBB");
        list.push("CCCC");
        list.push("DDDD");
        Log.d(TAG, "zwm, push list: " + list);
    }

    public void testPeekStack() {
        Log.d(TAG, "zwm, peek: " + list.peek());
        Log.d(TAG, "zwm, peek list: " + list);
    }

    public void testPopStack() {
        Log.d(TAG, "zwm, pop: " + list.pop());
        Log.d(TAG, "zwm, pop list: " + list);
    }
    //LinkedList实现栈 end

    //LinkedList实现队列 start
    public void testOfferQueue() {
        list.offer("AAAAA");
        list.offer("BBBBB");
        list.offer("CCCCC");
        Log.d(TAG, "zwm, offer list: " + list);
    }

    public void testAddQueue() {
        list.add("DDDDD");
        list.add("EEEEE");
        list.add("FFFFF");
        Log.d(TAG, "zwm, add list: " + list);
    }

    public void testPeekQueue() {
        Log.d(TAG, "zwm, peek: " + list.peek());
        Log.d(TAG, "zwm, peek list: " + list);
    }

    public void testElementQueue() {
        Log.d(TAG, "zwm, element: " + list.element());
        Log.d(TAG, "zwm, element list: " + list);
    }

    public void testPollQueue() {
        Log.d(TAG, "zwm, poll: " + list.poll());
        Log.d(TAG, "zwm, poll list: " + list);
    }

    public void testRemoveQueue() {
        Log.d(TAG, "zwm, remove: " + list.remove());
        Log.d(TAG, "zwm, remove list: " + list);
    }
    //LinkedList实现队列 end
}

//测试代码
private void testMethod() {
    Log.d(TAG, "zwm, testMethod");
    TestLinkedList linkedList = new TestLinkedList();
    linkedList.testAdd();
    linkedList.testAddFirst();
    linkedList.testAddLast();
    linkedList.testAdd2();
    linkedList.testAddAll();
    linkedList.testAddAll2();
    linkedList.testGet();
    linkedList.testGetFirst();
    linkedList.testGetLast();
    linkedList.testIndexOf();
    linkedList.testLastIndexOf();
    linkedList.testClone();
    linkedList.testContains();
    linkedList.testContainsAll();
    linkedList.testSize();
    linkedList.testClear();
    linkedList.testEmpty();
    linkedList.testAdd();
    linkedList.testIterator();
    linkedList.testIterator2();
    linkedList.testAdd();
    linkedList.testIterator3();
    linkedList.testDescendingIterator();
    linkedList.testRemove();
    linkedList.testRemove2();
    linkedList.testRemove3();
    linkedList.testRemoveFirst();
    linkedList.testRemoveLast();
    linkedList.testAdd();
    linkedList.testRemoveAll();
    linkedList.testAdd();
    linkedList.testElement();
    linkedList.testRetainAll();
    linkedList.testSet();
    linkedList.testSubList();
    linkedList.testToArray();
    linkedList.testToArray2();
    linkedList.testClear();
    linkedList.testPushStack();
    linkedList.testPeekStack();
    linkedList.testPopStack();
    linkedList.testClear();
    linkedList.testOfferQueue();
    linkedList.testAddQueue();
    linkedList.testPeekQueue();
    linkedList.testElementQueue();
    linkedList.testPollQueue();
    linkedList.testRemoveQueue();
}

//输出log
2019-08-14 15:35:38.260 zwm, testMethod
2019-08-14 15:35:38.264 zwm, add list: [a, b, c]
2019-08-14 15:35:38.264 zwm, addFirst list: [first, a, b, c]
2019-08-14 15:35:38.264 zwm, addLast list: [first, a, b, c, last]
2019-08-14 15:35:38.265 zwm, add index list: [ii, jj, kk, first, a, b, c, last]
2019-08-14 15:35:38.266 zwm, addAll list: [ii, jj, kk, first, a, b, c, last, lll, mmm, nnn]
2019-08-14 15:35:38.266 zwm, addAll index list: [xxxx, zzzz, yyyy, zzzz, ii, jj, kk, first, a, b, c, last, lll, mmm, nnn]
2019-08-14 15:35:38.266 zwm, get index 2: yyyy
2019-08-14 15:35:38.266 zwm, getFirst: xxxx
2019-08-14 15:35:38.267 zwm, getLast: nnn
2019-08-14 15:35:38.267 zwm, indexOf zzzz: 1
2019-08-14 15:35:38.267 zwm, lastIndexOf zzzz: 3
2019-08-14 15:35:38.268 zwm, list.equals(cloneList): true
2019-08-14 15:35:38.268 zwm, list==cloneList: false
2019-08-14 15:35:38.268 zwm, contains zzzz: true
2019-08-14 15:35:38.268 zwm, containsAll: true
2019-08-14 15:35:38.268 zwm, size: 15
2019-08-14 15:35:38.268 zwm, clear list: []
2019-08-14 15:35:38.269 zwm, isEmpty: true
2019-08-14 15:35:38.269 zwm, add list: [a, b, c]
2019-08-14 15:35:38.269 zwm, iterator item: a
2019-08-14 15:35:38.269 zwm, iterator item: b
2019-08-14 15:35:38.269 zwm, iterator item: c
2019-08-14 15:35:38.269 zwm, listIterator item: a
2019-08-14 15:35:38.269 zwm, listIterator item: b
2019-08-14 15:35:38.269 zwm, remove b
2019-08-14 15:35:38.270 zwm, listIterator item: c
2019-08-14 15:35:38.270 zwm, update c to x
2019-08-14 15:35:38.270 zwm, listIterator list: [a, x]
2019-08-14 15:35:38.270 zwm, next index: 2
2019-08-14 15:35:38.270 zwm, previous index: 1
2019-08-14 15:35:38.270 zwm, listIterator item: x
2019-08-14 15:35:38.270 zwm, listIterator item: a
2019-08-14 15:35:38.271 zwm, add list: [a, x, a, b, c]
2019-08-14 15:35:38.271 zwm, listIterator index item: a
2019-08-14 15:35:38.271 zwm, listIterator index item: b
2019-08-14 15:35:38.271 zwm, listIterator index item: c
2019-08-14 15:35:38.271 zwm, descendingIterator item: c
2019-08-14 15:35:38.272 zwm, descendingIterator item: b
2019-08-14 15:35:38.272 zwm, descendingIterator item: a
2019-08-14 15:35:38.272 zwm, descendingIterator item: x
2019-08-14 15:35:38.272 zwm, descendingIterator item: a
2019-08-14 15:35:38.272 zwm, remove a: true
2019-08-14 15:35:38.272 zwm, remove list: [x, a, b, c]
2019-08-14 15:35:38.272 zwm, remove index 3: c
2019-08-14 15:35:38.273 zwm, remove index list: [x, a, b]
2019-08-14 15:35:38.273 zwm, remove: x
2019-08-14 15:35:38.273 zwm, remove list: [a, b]
2019-08-14 15:35:38.273 zwm, removeFirst list: [b]
2019-08-14 15:35:38.273 zwm, removeLast list: []
2019-08-14 15:35:38.273 zwm, add list: [a, b, c]
2019-08-14 15:35:38.274 zwm, removeAll: true
2019-08-14 15:35:38.274 zwm, removeAll list: [c]
2019-08-14 15:35:38.274 zwm, add list: [c, a, b, c]
2019-08-14 15:35:38.274 zwm, element: c
2019-08-14 15:35:38.275 zwm, element list: [c, a, b, c]
2019-08-14 15:35:38.275 zwm, retainAll: false
2019-08-14 15:35:38.275 zwm, retainAll list: [c, a, b, c]
2019-08-14 15:35:38.276 zwm, set list: [sss, a, b, c]
2019-08-14 15:35:38.276 zwm, subList: [a, b]
2019-08-14 15:35:38.276 zwm, toArray item: sss
2019-08-14 15:35:38.276 zwm, toArray item: a
2019-08-14 15:35:38.276 zwm, toArray item: b
2019-08-14 15:35:38.277 zwm, toArray item: c
2019-08-14 15:35:38.277 zwm, toArray T param item: sss
2019-08-14 15:35:38.277 zwm, toArray T param item: a
2019-08-14 15:35:38.277 zwm, toArray T param item: b
2019-08-14 15:35:38.277 zwm, toArray T param item: c
2019-08-14 15:35:38.277 zwm, toArray T result item: sss
2019-08-14 15:35:38.277 zwm, toArray T result item: a
2019-08-14 15:35:38.277 zwm, toArray T result item: b
2019-08-14 15:35:38.277 zwm, toArray T result item: c
2019-08-14 15:35:38.277 zwm, clear list: []
2019-08-14 15:35:38.278 zwm, push list: [DDDD, CCCC, BBBB, AAAA]
2019-08-14 15:35:38.278 zwm, peek: DDDD
2019-08-14 15:35:38.278 zwm, peek list: [DDDD, CCCC, BBBB, AAAA]
2019-08-14 15:35:38.278 zwm, pop: DDDD
2019-08-14 15:35:38.278 zwm, pop list: [CCCC, BBBB, AAAA]
2019-08-14 15:35:38.279 zwm, clear list: []
2019-08-14 15:35:38.279 zwm, offer list: [AAAAA, BBBBB, CCCCC]
2019-08-14 15:35:38.279 zwm, add list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.279 zwm, peek: AAAAA
2019-08-14 15:35:38.280 zwm, peek list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, element: AAAAA
2019-08-14 15:35:38.280 zwm, element list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, poll: AAAAA
2019-08-14 15:35:38.280 zwm, poll list: [BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, remove: BBBBB
2019-08-14 15:35:38.281 zwm, remove list: [CCCCC, DDDDD, EEEEE, FFFFF]

三、原理

重要参数

//当前结点个数
transient int size = 0;  

//第一个结点
transient Node<E> first;  

//最后一个结点
transient Node<E> last;  

//链表结点类
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;
    }
}

构造函数

//初始化时size为0,first和last的结点都为空
public LinkedList() {
}

//初始化时将Collection中的所有元素添加到链表中
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

public boolean add(E e)

//添加一个元素到链表末尾
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 = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}

public void add(int index, E element)

//在索引位置添加元素
public void add(int index, E element) {
    checkPositionIndex(index);

    if (index == size)
        linkLast(element);
    else
        linkBefore(element, node(index));
}

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++;
}

public void addFirst(E e)

//添加一个元素到链表头部
public void addFirst(E e) {
    linkFirst(e);
}

public void addLast(E e)

//添加一个元素到链表末尾
public void addLast(E e) {
    linkLast(e);
}

public boolean addAll(Collection<? extends E> c)

//添加Collection中的所有元素到链表末尾
public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}

public boolean addAll(int index, Collection<? extends E> c)

//添加Collection中的所有元素到链表索引位置
public boolean addAll(int index, Collection<? extends E> c) {
    checkPositionIndex(index);

    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;
}

public boolean remove(Object o)

//移除链表中与对象o相等的元素
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;
}

public E remove(int index)

//移除链表中索引位置的元素
public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));
}

public E removeFirst()

//移除第一个元素
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

public E removeLast()

//移除最后一个元素
public E removeLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return unlinkLast(l);
}

public E get(int index)

//获取索引位置的元素
public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
}

public E getFirst()

//获取链表表头元素
public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

public E getLast()

//获取链表表尾元素
public E getLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return l.item;
}

public E set(int index, E element)

//将index位置的元素更改为element
public E set(int index, E element) {
    checkElementIndex(index);
    Node<E> x = node(index);
    E oldVal = x.item;
    x.item = element;
    return oldVal;
}

public int indexOf(Object o)

//从头到尾查找与对象o相等的元素的索引位置
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;
}

public int lastIndexOf(Object o)

//从尾到头查找与对象o相等的元素的索引位置
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;
}

public int size()

//获取链表元素个数
public int size() {
    return size;
}

public void clear()

//清空链表
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;
        x.next = null;
        x.prev = null;
        x = next;
    }
    first = last = null;
    size = 0;
    modCount++;
}

private class ListItr implements ListIterator<E>

private class DescendingIterator implements Iterator<E>

public void push(E e)

//将元素压入栈顶
public void push(E e) {
    addFirst(e);
}

public E peek()

//获取栈顶元素
public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}

public E pop()

//移除栈顶元素
public E pop() {
    return removeFirst();
}

public boolean offer(E e)

//将元素插入到队列尾部
public boolean offer(E e) {
    return add(e);
}

public E element()

//获取队列头部元素
public E element() {
    return getFirst();
}

public E poll()

//移除队列头部元素
public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

四、主题

链表

相关文章

网友评论

      本文标题:JDK源码 -- LinkedList

      本文链接:https://www.haomeiwen.com/subject/ngamjctx.html