我所理解的JKD集合類(四):手寫LinkedList實現List接口

package cn.test;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * @Description : 手寫LinkedList的實現  
 * @Author : houshuiqiang@163.com, 2016年5月1日 下午3:55:12  
 * @Modified :houshuiqiang@163.com, 2016年5月2日  
 */
public class MyLinkedList<E> implements List<E> {

    private int modCount; // 更新次數 -- eg: 遍歷的時候使用list.remove()會報錯。使用iterator.remove()不會報錯

    private int size;

    private Node<E> firstNode;

    private Node<E> lastNode;

    public MyLinkedList () {
        super();
        firstNode = null;
        lastNode = null;
    }

    @SuppressWarnings("null")
    public MyLinkedList (Node<E> firstNode, Node<E> lastNode) {
        this.firstNode = firstNode;
        this.lastNode = lastNode;

        for (Node<E> tempNode = firstNode; tempNode == null; tempNode = tempNode.nextNode) {
            size++;
        }
    }

    @SuppressWarnings("unchecked")
    public MyLinkedList (Collection<?> c) {
        for (Object obj : c) {
            this.add((E)obj);
        }
    }


    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    public Iterator<E> iterator() {
        return new MyListIterator(firstNode);
    }

    public Object[] toArray() {
        Object[] array = new Object[size];
        int index = 0;
        for (Node<E> tempNode = firstNode; tempNode != null; tempNode = tempNode.nextNode) {
            array[index++] = tempNode.e;
        }
        return array;
    }

    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        int index = 0;
        for (Node<E> tempNode = firstNode; tempNode != null; tempNode = tempNode.nextNode) {
            if (index < a.length) {
                a[index++] = (T)tempNode.e;
            }else{
                break;
            }
        }
        return a;
    }

    public boolean add(E e) {
        Node<E> last_1 = lastNode;

        Node<E> last = new Node<E>(e, last_1, null);

        if (size != 0) {
            last_1.nextNode = last;
        }else {
            firstNode = last;
        }

        lastNode = last;
        size++;
        modCount++;
        return true;
    }

    public boolean remove(Object o) {
        for (Node<E> tempNode = firstNode; tempNode != null; tempNode = tempNode.nextNode) {
            if (o == null && tempNode.e == null || o != null && o.equals(tempNode.e)) {

                if (tempNode.preNode != null) {
                    tempNode.preNode.nextNode = tempNode.nextNode;
                }
                if (tempNode.nextNode != null) {
                    tempNode.nextNode.preNode = tempNode.preNode;
                }

                size--;
                modCount++;
                return true;
            }
        }
        return false;
    }

    public boolean containsAll(Collection<?> c) {
        for (Object object : c) {
            if (! contains(object)) {
                return false;
            }
        }
        return true;
    }

    public boolean addAll(Collection<? extends E> c) {
        return addAll(0, c);
    }

    public boolean addAll(int index, Collection<? extends E> c) {
        if (index > size) {
            throw new IndexOutOfBoundsException();
        }
        MyLinkedList<E> list = new MyLinkedList<E>(c);

        if (index == size) {
            Node<E> last_index = lastNode;
            last_index.nextNode = list.firstNode;
            lastNode = list.lastNode;
        }else {
            Node<E> indexNode = getIndex(index);

            indexNode.preNode.nextNode = list.firstNode;
            list.firstNode.preNode = indexNode.preNode;
            list.lastNode.nextNode = indexNode;
            indexNode.preNode = list.lastNode;
        }

        size += c.size();
        modCount++;
        return true;
    }

    public boolean removeAll(Collection<?> c) {
        boolean flag = false;
        for (Object obj : c) {
            if (remove(obj)){
                flag = true;
            }
        }
        return flag;
    }

    public boolean retainAll(Collection<?> c) {
        int size = this.size;
        for (Object object : c) {
            if (indexOf(object) == -1) {
                remove(object);
            }
        }
        return size == this.size;
    }

    public void clear() {
        firstNode = null;
        lastNode = null;
        size = 0;
        modCount++;
    }

    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        return getIndex(index).e;
    }

    public E set(int index, E element) {
        if (index > size) {
            throw new IndexOutOfBoundsException();
        }
        if (index == size) {
            Node<E> node = new Node<E>(element, lastNode, null);
            lastNode = node;
        }else {
            Node<E> indexNode = getIndex(index);
            Node<E> node = new Node<E>(element, indexNode.preNode, null);
            node.nextNode = indexNode.nextNode;
        }
        return element;
    }

    public void add(int index, E element) {
        if (index > size) {
            throw new IndexOutOfBoundsException();
        }
        if (index == size) {
            Node<E> node = new Node<E>(element, lastNode, null);
            lastNode = node;
        }else {
            Node<E> indexNode = getIndex(index);
            Node<E> node = new Node<E>(element, indexNode.preNode, null);
            node.nextNode = indexNode;
        }
        size++;
        modCount++;
    }

    public E remove(int index) {
        if (index >= size) {
            throw new IndexOutOfBoundsException();
        }
        Node<E> indexNode = getIndex(index);

        Node<E> preNode = indexNode.preNode;
        Node<E> nextNode = indexNode.nextNode;

        preNode.nextNode = nextNode;
        nextNode.preNode = preNode;

        size--;
        modCount++;

        return indexNode.e;
    }

    public int indexOf(Object o) {
        int index = 0;
        for (Node<E> tempNode = firstNode; tempNode != null; tempNode = tempNode.nextNode) {
            index++;
            if (tempNode.e.equals(o)){
                return --index;
            }
        }
        return -1;
    }

    public int lastIndexOf(Object o) {
        int index = size;
        for (Node<E> tempNode = lastNode; tempNode != null; tempNode = tempNode.preNode) {
            index--;
            if (tempNode.e.equals(o)){
                return ++index;
            }
        }
        return -1;
    }

    public ListIterator<E> listIterator() {
        return new MyListIterator(firstNode);
    }

    public ListIterator<E> listIterator(int index) {
        return new MyListIterator(getIndex(index));
    }

    public List<E> subList(int fromIndex, int toIndex) {
        Node<E> fromNode = getIndex(fromIndex);
        Node<E> toNode = getIndex(toIndex);

        return new MyLinkedList<E>(fromNode, toNode);
    }

    private Node<E> getIndex(int index){
        int tempIndex = 0;
        Node<E> indexNode = null;
        for (Node<E> tempNode = firstNode; tempNode != null; tempNode = tempNode.nextNode) {
            if (tempIndex == index) {
                indexNode =  tempNode;
                break;
            }
            tempIndex++;
        }
        return indexNode;
    }


    @SuppressWarnings("hiding")
    private class Node<E> {
        E e;
        Node<E> preNode;
        Node<E> nextNode;
        public Node(E e, Node<E> preNode, Node<E> nextNode) {
            super();
            this.e = e;
            this.preNode = preNode;
            this.nextNode = nextNode;
        }
    }

    private class MyListIterator implements ListIterator<E> {

        private int itrModCount = modCount;

        private Node<E> nextReturnNode; // 下次要返回的

        private Node<E> lastReturnedNode; // 最近返回的

        public MyListIterator(Node<E> currentNode) {
            if (currentNode == null) {
                throw new IllegalArgumentException("構造參數不能爲null");
            }
            this.nextReturnNode = currentNode;
        }

        @Override
        public boolean hasNext() {
            return nextReturnNode != null;
        }

        @Override
        public E next() {

            checkModCount();

            E e = nextReturnNode.e;
            lastReturnedNode = nextReturnNode;
            nextReturnNode = nextReturnNode.nextNode;

            return e;
        }

        @Override
        public void remove(){

            checkModCount();

            size--;
            modCount++;
            itrModCount = modCount;

            if (nextReturnNode == null) {
                lastNode = lastReturnedNode.preNode;
                if (lastNode != null) lastNode.nextNode = null;
                return;
            }
            if (lastReturnedNode.preNode == null) {
                firstNode = nextReturnNode;
                firstNode.preNode = null;
                return;
            }

            lastReturnedNode.preNode.nextNode = nextReturnNode;
            nextReturnNode.preNode = lastReturnedNode.preNode;
        }

        @Override
        public void add(E e) {

            checkModCount();

            Node<E> tempNode = new Node<E>(e, lastReturnedNode, nextReturnNode);
            lastReturnedNode.nextNode = tempNode;
            if (nextReturnNode != null) nextReturnNode.preNode = tempNode;

            size++;
            modCount++;
            itrModCount = modCount;
        }

        @Override
        public boolean hasPrevious() {
            return lastReturnedNode != null;
        }

        @Override
        public int nextIndex() {
            return indexOf(nextReturnNode);
        }

        @Override
        public E previous() {

            checkModCount();

            E e = lastReturnedNode.e;
            nextReturnNode = lastReturnedNode;
            lastReturnedNode = lastReturnedNode == null ? null : lastReturnedNode.preNode;
            return e;
        }

        @Override
        public int previousIndex() {
            return indexOf(lastReturnedNode);
        }

        @Override
        public void set(E e) {
            checkModCount();
            lastReturnedNode.e = e;
        }

        private void checkModCount(){
            if (this.itrModCount != MyLinkedList.this.modCount) throw new RuntimeException("遍歷期間不能增刪元素,若是須要,請使用iterator的函數");
        }

    }
}

LinkedList底層使用雙向鏈表結構,在add()元素的時候很快速。在remove()元素的時候,須要先定位到元素再進行刪除。定位元素至關因而遍歷,鏈表長的話比較耗時。一旦定位到元素,刪除很快。這屬於數據結構方面的優缺點。java

相關文章
相關標籤/搜索