JDK源码学习之LinkedList和Vector

LinkedList

LinkedList我个人更偏向刷题和工程中使用,当然。面试的时候也有可能会被问道linkedList,所以,我们继续去了解LinkedList的底层源码。这样我们无论是在面试,还是在工程使用,亦或者刷题中优化代码时空复杂度,我们都能有迹可循,而不是一头雾水。

第一章:LinkedListArrayList的孪生兄弟

其实大家如果对List集合有一定了解,都会知道ArrayListLinkedList是极为相似的。本质上就是存储的结构不一样,一个是基于线性表,一个是基于链表

所以这一块并没有什么好说的,我们只需要关注LinkedList在链表结构上的设计特点即可。

一样的,我们在第一行也就是类名上,看到 LinkedListArrayList不同的是,其实现了 Deque。那什么是Deque,它的作用是什么呢?接下来我会给大家徐徐道来。

A linear collection that supports element insertion and removal at both ends.  The name <i>deque</i> is short for "double ended queue" and is usually pronounced "deck".
一个线性集合。支持在两端插入和删除元素。其实也就是我们常说的双端队列
This interface defines methods to access the elements at both ends of the deque.  Methods are provided to insert, remove, and examine the element.
此接口定义了访问 deque 两端元素的方法。提供了用于插入、删除和检查元素的方法。

所以说,这个接口实际上就是定义了一个规范:实现了该接口的容器一定是一个能支持双端对元素进行操作的容器。

接下来我们来看其构造方法:

构造方法

public LinkedList() {
    }
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

ADD

public boolean addAll(int index, Collection<? extends E> c) {
		//检查index合法性
        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 {
        	//获取index位置的节点元素
            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 add(E e) {
    	//添加元素到队尾
        linkLast(e);
        return true;
    }
    
    public void add(int index, E element) {
        checkPositionIndex(index);

        if(index == size) {
            // 将指定的元素添加到链表结尾
            linkLast(element);
        } else {
            // 获取index处的结点
            Node<E> node = node(index);

            // 将元素element插入为node的前驱
            linkBefore(element, node);
        }
    }
    
    // 将指定的元素添加到链表结尾
    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++;
    }
    
    // 从双向链表头部加入,链表满时返回false
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }
    
    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++;
    }
    
    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++;
    }
    
    

DEL

public E remove(int index) {
        checkElementIndex(index);
        // 获取index处的结点
        Node<E> node = node(index);
        // 将元素node从链表中移除
        return unlink(node);
    }
    
 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 void clear() {
        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++;
    }
 
 //将元素x从链表中移除
 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;
    }

GET

    // 获取指定索引处的元素
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    //获取index节点
    Node<E> node(int 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;
        }
    }
    
    // 返回指定元素的首位逆序索引(逆序查找首个匹配的元素)
    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;
    }

SET

    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }

上面的操作其实都大差不差,因为在 LinkedList中已经定义了头节点和尾节点,基本所有的操作都是基于链表的操作,所以大家如果熟悉链表操作的话基本上看看就行。主要是设计思想。

至于其他的序列化、克隆方法,这里就不再重复赘述,本质上是一个道理,举一反三即可。


Vector

vector可以看作是线程安全类的 ArrayList集合。因为本质上也是线性数组存储元素,且同时支持高速随机查找。

由于 vector容器内方法与之前两个容器有相似的地方,故这里不再给出代码,具体来说为什么是线程安全的 ArrayList。因为在对于数据做改变的地方显示的加上了sync锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值