Java基础之List集合(包含JUC)学习进程(一)

Java中重要的集合包主要有Collection和map
复习collectioon,主要是List,Queue和Set

List

首先要知道List是一个接口,继承自collection
其中定义了是元素有序并且可以重复的集合,被称为序列,并且List允许存放null
因为有序,所以List是可以精确的控制元素的插入位置或删除某个位置元素
注意List(如java数组)下标index从0开始计数.
现在看一下list中都有哪些常用方法
(1)查询操作

  
//list中元素个数    
 int size();    
//非空查询  
 boolean isEmpty();    
//是否包含某对象o   
 boolean contains(Object o);   
//迭代器
 Iterator<E> iterator();
//返回一个包含list中所有元素的数组(元素顺序和list中一致);
//运行时返回类型和参数数组一致
 Object[] toArray();
 
   

(2)修改操作

//插入到List表尾
boolean add(E e);

//删除list中首次出现的指定值(如果存在),如果不存在,则不进行任何操作.
boolean remove(Object o);

//移除list中的所有元素.
void clear();

//sort采用的是归并排序
default void sort(Comparator<? super E> c)
 {      
//获取当前list中所有对象 
Object[] a = this.toArray();     
//根据比较器c对a排序
Arrays.sort(a, (Comparator) c);    
 //利用迭代器将数组中的元素类型进行强制转型,到原来list中的类型        ListIterator<E> i = this.listIterator();    
for (Object e : a)
    {          
        i.next();        
        i.set((E) e);   
                         }   
         }
 //equals方法
/**
     * 比较传入对象o和当前list的等价性.
     * 相等条件:
     * 1.o类型为list
     * 2.二者size大小一样
     * 3.list中包含的元素顺序一致.
     */
    boolean equals(Object o);

查找操作

 //查找元素首次在list中出现的位置,不存在返回-1
int indexOf(Object o);   
 //查找元素最后一次在list中出现的位置,不存在返回-1
int lastIndexOf(Object o);
//返回子集
List<E> subList(int fromIndex, int toIndex);

List的基本的实现类有以下四个
ArrayList
LinkedList
Vector
Stack

ArrayList是数组实现的队列,它是一个动态数组;它不是线程安全的,只适用于单线程。
LinkedList是双向链表实现的双端队列;它不是线程安全的,只适用于单线程。
Vector是数组实现的矢量队列,它也一个动态数组;不过和ArrayList不同的是,Vector是线程安全的,它支持并发。
Stack是Vector实现的栈;和Vector一样,它也是线程安全的

并且在JUC中对List还有进一步的实现类
CopyOnWriteArrayList
它相当于线程安全的ArrayList,它实现了List接口。CopyOnWriteArrayList是支持高并发的,后面会介绍。

一一来介绍

ArrayList

ArrayList是数组实现的,即动态数组,可以动态的增加和减少元素,他实现了ICollection和IList接口,可以灵活的设置数组的大小所有优势在于遍历查询操作快,缺点在于插入删除会比较慢。
相比较数组而言,在1.8中,如果只是new ArrayList() ,容量是0,当第一次通过add(E e)时,才扩充为10。之后每次扩容就会以当前容量两倍扩容,这是比较影响效率的,所以需要大容量的时候,在一开始定义一个合适的ArrayList的大小是有必要的。
其次,对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作也可能会影响一部分效率
源码如下

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;
    //默认的初始容量为10
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    transient Object[] elementData; 
    // ArrayList中实际数据的数量
    private int size;
    public ArrayList(int initialCapacity) //带初始容量大小的构造函数
    {
        if (initialCapacity > 0)   //初始容量大于0,实例化数组
        {
            this.elementData = new Object[initialCapacity];
        } 
        else if (initialCapacity == 0) //初始化等于0,将空数组赋给elementData
        {
            this.elementData = EMPTY_ELEMENTDATA;  
        } 
        else    //初始容量小于,抛异常
        {
            throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
        }
    }
    public ArrayList()  //无参构造函数,默认容量为10
    {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    public ArrayList(Collection<? extends E> c)  //创建一个包含collection的ArrayList
    {
        elementData = c.toArray(); //返回包含c所有元素的数组
        if ((size = elementData.length) != 0)
        {
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);//复制指定数组,使elementData具有指定长度
        } 
        else
        {
            //c中没有元素
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    //将当前容量值设为当前实际元素大小
    public void trimToSize()
    {
        modCount++;
        if (size < elementData.length) 
        {
            elementData = (size == 0)? EMPTY_ELEMENTDATA:Arrays.copyOf(elementData, size);
        }
    }
    
    //将集合的capacit增加minCapacity
    public void ensureCapacity(int minCapacity) 
    {
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)?0:DEFAULT_CAPACITY;
        if (minCapacity > minExpand)
        {
            ensureExplicitCapacity(minCapacity);
        }
    }
    private void ensureCapacityInternal(int minCapacity)
    {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }
    private void ensureExplicitCapacity(int minCapacity)
    {
        modCount++;
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    private void grow(int minCapacity)
    {
        int oldCapacity = elementData.length;
     //注意此处扩充capacity的方式是将其向右一位再加上原来的数,实际上是扩充了1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    private static int hugeCapacity(int minCapacity) 
    {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
    //返回ArrayList的大小
    public int size()
    {
        return size;
    }
    //判断ArrayList是否为空
    public boolean isEmpty() {
        return size == 0;
    }
    //判断ArrayList中是否包含Object(o)
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
    //正向查找,返回ArrayList中元素Object(o)的索引位置
    public int indexOf(Object o)
    {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } 
        else
        {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    //逆向查找,返回返回ArrayList中元素Object(o)的索引位置
    public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    //返回此 ArrayList实例的浅拷贝。
    public Object clone() 
    {
        try 
        {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } 
        catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
    //返回一个包含ArrayList中所有元素的数组
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }
    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }
    
    //返回至指定索引的值
    public E get(int index) 
    {
        rangeCheck(index); //检查给定的索引值是否越界
        return elementData(index);
    }
   
    //将指定索引上的值替换为新值,并返回旧值
    public E set(int index, E element)   
    {
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
    
    //将指定的元素添加到此列表的尾部
    public boolean add(E e) 
    {
        ensureCapacityInternal(size + 1);  
        elementData[size++] = e;
        return true;
    }
    
    // 将element添加到ArrayList的指定位置   
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1); 
       
        //从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
        //arraycopy(被复制的数组, 从第几个元素开始复制, 要复制到的数组, 从第几个元素开始粘贴, 一共需要复制的元素个数)
        //即在数组elementData从index位置开始,复制到index+1位置,共复制size-index个元素
        System.arraycopy(elementData, index, elementData, index + 1,size - index);
        elementData[index] = element;
        size++;
    }
    
    //删除ArrayList指定位置的元素  
    public E remove(int index)
    {
        rangeCheck(index);
        modCount++;
        E oldValue = elementData(index);
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,numMoved);
        elementData[--size] = null; //将原数组最后一个位置置为null
        return oldValue;
    }
    
    //移除ArrayList中首次出现的指定元素(如果存在)。
    public boolean remove(Object o) {
        if (o == null) 
        {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null)
                {
                    fastRemove(index);
                    return true;
                }
        } 
        else
        {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index]))
                {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    
    //快速删除指定位置的元素
    private void fastRemove(int index)
    {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index, numMoved);
        elementData[--size] = null; 
    }
   
    //清空ArrayList,将全部的元素设为null
    public void clear() 
    {
        modCount++;
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
    }
    
    //按照c的迭代器所返回的元素顺序,将c中的所有元素添加到此列表的尾部
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    //从指定位置index开始,将指定c中的所有元素插入到此列表中
    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        int numMoved = size - index;
        if (numMoved > 0)
            //先将ArrayList中从index开始的numMoved个元素移动到起始位置为index+numNew的后面去
            System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
        //再将c中的numNew个元素复制到起始位置为index的存储空间中去
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    //删除fromIndex到toIndex之间的全部元素
    protected void removeRange(int fromIndex, int toIndex)
    {
        modCount++;
        //numMoved为删除索引后面的元素个数
        int numMoved = size - toIndex;  
        //将删除索引后面的元素复制到以fromIndex为起始位置的存储空间中去
        System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);
        int newSize = size - (toIndex-fromIndex);
        //将ArrayList后面(toIndex-fromIndex)个元素置为null
        for (int i = newSize; i < size; i++)
        {
            elementData[i] = null;
        }
        size = newSize;
    }
    
    //检查索引是否越界
    private void rangeCheck(int index)
    {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    private void rangeCheckForAdd(int index) 
    {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }
    
    //删除ArrayList中包含在c中的元素
    public boolean removeAll(Collection<?> c)
    {
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }
    
    //删除ArrayList中除包含在c中的元素,和removeAll相反
    public boolean retainAll(Collection<?> c) 
    {
        Objects.requireNonNull(c);  //检查指定对象是否为空
        return batchRemove(c, true);
    }
    
    private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try 
        {
            for (; r < size; r++)
                if (c.contains(elementData[r]) == complement)  //判断c中是否有elementData[r]元素

                    elementData[w++] = elementData[r];
        }
        finally 
        {
            if (r != size) 
            {
                System.arraycopy(elementData, r, elementData, w, size - r);
                w += size - r;
            }
            if (w != size) 
            {
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }
    
    //将ArrayList的“容量,所有的元素值”都写入到输出流中 
    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException
    {
        int expectedModCount = modCount;
        s.defaultWriteObject();
        //写入数组大小
        s.writeInt(size);
        //写入所有数组的元素
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }
    
    //先将ArrayList的“大小”读出,然后将“所有的元素值”读出
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;
        s.defaultReadObject();
        s.readInt(); // ignored
        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            ensureCapacityInternal(size);
            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }
    }

LinkedList

LinkedList特性
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。
LinkedList相对于ArrayList来说,它是基于链表实现的,支持随机存储,但不支持高效的随机元素访问。ArrayList的空间浪费主要体现在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间,就存储密度来说,ArrayList是优于LinkedList的。
源码如下

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
   //实现Serilizable接口时,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
    transient int size = 0;
    //指向首节点
    transient Node<E> first;
    //指向最后一个节点
    transient Node<E> last;
    //构建一个空列表
    public LinkedList() {
    }
    //构建一个包含集合c的列表
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
   //将节点值为e的节点作为首节点
    private void linkFirst(E e) {
        final Node<E> f = first;
        //构建一个prev值为null,next为f,节点值为e的节点
        final Node<E> newNode = new Node<>(null, e, f);
        //将newNode作为首节点
        first = newNode;
        //如果newNode后面没有节点就将newNode作为最后一个节点
        if (f == null)
            last = newNode;
        //否则就将newNode赋给其prev
        else
            f.prev = newNode;
        //列表长度加一
        size++;
        modCount++;
    }
    //将节点值为e的节点作为最后一个节点
    void linkLast(E e) {
        final Node<E> l = last;
      //构建一个prev值为l,next为null,节点值为e的节点
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
    //在非空节点succ之前插入节点e
    void linkBefore(E e, Node<E> succ) {
        final Node<E> pred = succ.prev;
        //将succ前面的节点和succ作为其prev和next
        final Node<E> newNode = new Node<>(pred, e, succ);
        //然后将newNode作为succ的prev
        succ.prev = newNode; 
        //如果原来succ是首节点,则将newNode设置为首节点
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }
     //释放非空的首节点f
    private E unlinkFirst(Node<E> f) {
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        //将first节点后面的节点设为首节点
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }
     //释放非空的尾节点l
       private E unlinkLast(Node<E> l) {
        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;
    }
    //删除非空节点x
    E unlink(Node<E> x) 
    {
        final E element = x.item;
        final Node<E> next = x.next;    //x后面的节点
        final Node<E> prev = x.prev;    //x前面的节点

        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;
    }
    //返回列表首节点元素值
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
    //返列表尾节点元素值
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }
    //移除首节点
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }
   //删除尾节点
    public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }
  //在列表首部插入节点e
    public void addFirst(E e) {
        linkFirst(e);
    }
    //在列表尾部插入节点e
    public void addLast(E e) {
        linkLast(e);
    }
   //判断列表中是否包含有元素o
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }
    //返回列表长度大小
    public int size() {
        return size;
    }
    //在列表尾部插入元素
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    //删除元素为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;
    }
   //将集合c中所有元素添加到列表的尾部
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
   //从指定的位置index开始,将集合c中的元素插入到列表中
    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 {  //否则,找到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 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++;
    }
    //获取指定索引位置节点的元素值
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    //替换指定索引位置节点的元素值
    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }
    //在指定索引位置之前插入元素e
    public void add(int index, E element) {
        checkPositionIndex(index);   
        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    //删除指定位置的元素
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
    //判断指定索引位置的元素是否存在
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }
    //构建 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));
    }
    //返回指定索引位置的节点
    Node<E> node(int index) {
        //此处是一个小技巧,当index<size/2时,从列表前半部分开始,否则从后半部分开始
        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;
        }
    }//返回列表中第一次出现o的位置,若不存在则返回-1
    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;
    }
    //逆向搜索,返回第一出现o的位置,不存在则返回-1
    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 E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

    //获取列表首节点元素值,若为空则抛异常
    public E element() {
        return getFirst();
    }
   //检索首节点,若空则返回null,不为空则返回其元素值并删除首节点
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
    //检索首节点,若空则抛异常,不为空则返回其元素值并删除首节点
    public E remove() {
        return removeFirst();
    }
   //在列表尾部增加节点e
    public boolean offer(E e) {
        return add(e);
    }
   //在列表首部插入节点e
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }
  //在列表尾部插入节点e
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }
    public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }
  //获取列表尾节点元素值
    public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }
    public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
    public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }
   //入栈
    public void push(E e)
    {
        addFirst(e);
    }
    //出栈
    public E pop() {
        return removeFirst();
    }
    //删除列表中第一出现o的节点
    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }
    //逆向搜索,删除第一次出现o的节点
    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;
    }

Vector

Vector也是基于数组实现的,是一个动态数组,其容量能自动增长。 Vector的很多实现方法都加入了同步语句,因此是线程安全的,可以用于多线程环境。
Vector没有实现Serializable接口,因此它不支持序列化
Vector实现了Cloneable接口,能被克隆,实现了RandomAccess接口,支持快速随机访问。

源码

package java.util;  
 
public class Vector<E>  
    extends AbstractList<E>  
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
{  
     
    // 保存Vector中数据的数组  
    protected Object[] elementData;  
 
    // 实际数据的数量  
    protected int elementCount;  
 
    // 容量增长系数  
    protected int capacityIncrement;  
 
    // Vector的序列版本号  
    private static final long serialVersionUID = -2767605614048989439L;  
 
    // Vector构造函数。默认容量是10。  
    public Vector() {  
        this(10);  
    }  
 
    // 指定Vector容量大小的构造函数  
    public Vector(int initialCapacity) {  
        this(initialCapacity, 0);  
    }  
 
    // 指定Vector"容量大小"和"增长系数"的构造函数  
    public Vector(int initialCapacity, int capacityIncrement) {  
        super();  
        if (initialCapacity < 0)  
            throw new IllegalArgumentException("Illegal Capacity: "+  
                                               initialCapacity);  
        // 新建一个数组,数组容量是initialCapacity  
        this.elementData = new Object[initialCapacity];  
        // 设置容量增长系数  
        this.capacityIncrement = capacityIncrement;  
    }  
 
    // 指定集合的Vector构造函数。  
    public Vector(Collection<? extends E> c) {  
        // 获取“集合(c)”的数组,并将其赋值给elementData  
        elementData = c.toArray();  
        // 设置数组长度  
        elementCount = elementData.length;  
        // c.toArray might (incorrectly) not return Object[] (see 6260652)  
        if (elementData.getClass() != Object[].class)  
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);  
    }  
 
    // 将数组Vector的全部元素都拷贝到数组anArray中  
    public synchronized void copyInto(Object[] anArray) {  
        System.arraycopy(elementData, 0, anArray, 0, elementCount);  
    }  
 
    // 将当前容量值设为 =实际元素个数  
    public synchronized void trimToSize() {  
        modCount++;  
        int oldCapacity = elementData.length;  
        if (elementCount < oldCapacity) {  
            elementData = Arrays.copyOf(elementData, elementCount);  
        }  
    }  
 
    // 确认“Vector容量”的帮助函数  
    private void ensureCapacityHelper(int minCapacity) {  
        int oldCapacity = elementData.length;  
        // 当Vector的容量不足以容纳当前的全部元素,增加容量大小。  
        // 若 容量增量系数>0(即capacityIncrement>0),则将容量增大当capacityIncrement  
        // 否则,将容量增大一倍。  
        if (minCapacity > oldCapacity) {  
            Object[] oldData = elementData;  
            int newCapacity = (capacityIncrement > 0) ?  
                (oldCapacity + capacityIncrement) : (oldCapacity * 2);  
            if (newCapacity < minCapacity) {  
                newCapacity = minCapacity;  
            }  
            elementData = Arrays.copyOf(elementData, newCapacity);  
        }  
    }  
 
    // 确定Vector的容量。  
    public synchronized void ensureCapacity(int minCapacity) {  
        // 将Vector的改变统计数+1  
        modCount++;  
        ensureCapacityHelper(minCapacity);  
    }  
 
    // 设置容量值为 newSize  
    public synchronized void setSize(int newSize) {  
        modCount++;  
        if (newSize > elementCount) {  
            // 若 "newSize 大于 Vector容量",则调整Vector的大小。  
            ensureCapacityHelper(newSize);  
        } else {  
            // 若 "newSize 小于/等于 Vector容量",则将newSize位置开始的元素都设置为null  
            for (int i = newSize ; i < elementCount ; i++) {  
                elementData[i] = null;  
            }  
        }  
        elementCount = newSize;  
    }  
 
    // 返回“Vector的总的容量”  
    public synchronized int capacity() {  
        return elementData.length;  
    }  
 
    // 返回“Vector的实际大小”,即Vector中元素个数  
    public synchronized int size() {  
        return elementCount;  
    }  
 
    // 判断Vector是否为空  
    public synchronized boolean isEmpty() {  
        return elementCount == 0;  
    }  
 
    // 返回“Vector中全部元素对应的Enumeration”  
    public Enumeration<E> elements() {  
        // 通过匿名类实现Enumeration  
        return new Enumeration<E>() {  
            int count = 0;  
 
            // 是否存在下一个元素  
            public boolean hasMoreElements() {  
                return count < elementCount;  
            }  
 
            // 获取下一个元素  
            public E nextElement() {  
                synchronized (Vector.this) {  
                    if (count < elementCount) {  
                        return (E)elementData[count++];  
                    }  
                }  
                throw new NoSuchElementException("Vector Enumeration");  
            }  
        };  
    }  
 
    // 返回Vector中是否包含对象(o)  
    public boolean contains(Object o) {  
        return indexOf(o, 0) >= 0;  
    }  
 
 
    // 从index位置开始向后查找元素(o)。  
    // 若找到,则返回元素的索引值;否则,返回-1  
    public synchronized int indexOf(Object o, int index) {  
        if (o == null) {  
            // 若查找元素为null,则正向找出null元素,并返回它对应的序号  
            for (int i = index ; i < elementCount ; i++)  
            if (elementData[i]==null)  
                return i;  
        } else {  
            // 若查找元素不为null,则正向找出该元素,并返回它对应的序号  
            for (int i = index ; i < elementCount ; i++)  
            if (o.equals(elementData[i]))  
                return i;  
        }  
        return -1;  
    }  
 
    // 查找并返回元素(o)在Vector中的索引值  
    public int indexOf(Object o) {  
        return indexOf(o, 0);  
    }  
 
    // 从后向前查找元素(o)。并返回元素的索引  
    public synchronized int lastIndexOf(Object o) {  
        return lastIndexOf(o, elementCount-1);  
    }  
 
    // 从后向前查找元素(o)。开始位置是从前向后的第index个数;  
    // 若找到,则返回元素的“索引值”;否则,返回-1。  
    public synchronized int lastIndexOf(Object o, int index) {  
        if (index >= elementCount)  
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);  
 
        if (o == null) {  
            // 若查找元素为null,则反向找出null元素,并返回它对应的序号  
            for (int i = index; i >= 0; i--)  
            if (elementData[i]==null)  
                return i;  
        } else {  
            // 若查找元素不为null,则反向找出该元素,并返回它对应的序号  
            for (int i = index; i >= 0; i--)  
            if (o.equals(elementData[i]))  
                return i;  
        }  
        return -1;  
    }  
 
    // 返回Vector中index位置的元素。  
    // 若index月结,则抛出异常  
    public synchronized E elementAt(int index) {  
        if (index >= elementCount) {  
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);  
        }  
 
        return (E)elementData[index];  
    }  
 
    // 获取Vector中的第一个元素。  
    // 若失败,则抛出异常!  
    public synchronized E firstElement() {  
        if (elementCount == 0) {  
            throw new NoSuchElementException();  
        }  
        return (E)elementData[0];  
    }  
 
    // 获取Vector中的最后一个元素。  
    // 若失败,则抛出异常!  
    public synchronized E lastElement() {  
        if (elementCount == 0) {  
            throw new NoSuchElementException();  
        }  
        return (E)elementData[elementCount - 1];  
    }  
 
    // 设置index位置的元素值为obj  
    public synchronized void setElementAt(E obj, int index) {  
        if (index >= elementCount) {  
            throw new ArrayIndexOutOfBoundsException(index + " >= " +  
                                 elementCount);  
        }  
        elementData[index] = obj;  
    }  
 
    // 删除index位置的元素  
    public synchronized void removeElementAt(int index) {  
        modCount++;  
        if (index >= elementCount) {  
            throw new ArrayIndexOutOfBoundsException(index + " >= " +  
                                 elementCount);  
        } else if (index < 0) {  
            throw new ArrayIndexOutOfBoundsException(index);  
        }  
 
        int j = elementCount - index - 1;  
        if (j > 0) {  
            System.arraycopy(elementData, index + 1, elementData, index, j);  
        }  
        elementCount--;  
        elementData[elementCount] = null; /* to let gc do its work */ 
    }  
 
    // 在index位置处插入元素(obj)  
    public synchronized void insertElementAt(E obj, int index) {  
        modCount++;  
        if (index > elementCount) {  
            throw new ArrayIndexOutOfBoundsException(index  
                                 + " > " + elementCount);  
        }  
        ensureCapacityHelper(elementCount + 1);  
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);  
        elementData[index] = obj;  
        elementCount++;  
    }  
 
    // 将“元素obj”添加到Vector末尾  
    public synchronized void addElement(E obj) {  
        modCount++;  
        ensureCapacityHelper(elementCount + 1);  
        elementData[elementCount++] = obj;  
    }  
 
    // 在Vector中查找并删除元素obj。  
    // 成功的话,返回true;否则,返回false。  
    public synchronized boolean removeElement(Object obj) {  
        modCount++;  
        int i = indexOf(obj);  
        if (i >= 0) {  
            removeElementAt(i);  
            return true;  
        }  
        return false;  
    }  
 
    // 删除Vector中的全部元素  
    public synchronized void removeAllElements() {  
        modCount++;  
        // 将Vector中的全部元素设为null  
        for (int i = 0; i < elementCount; i++)  
            elementData[i] = null;  
 
        elementCount = 0;  
    }  
 
    // 克隆函数  
    public synchronized Object clone() {  
        try {  
            Vector<E> v = (Vector<E>) super.clone();  
            // 将当前Vector的全部元素拷贝到v中  
            v.elementData = Arrays.copyOf(elementData, elementCount);  
            v.modCount = 0;  
            return v;  
        } catch (CloneNotSupportedException e) {  
            // this shouldn't happen, since we are Cloneable  
            throw new InternalError();  
        }  
    }  
 
    // 返回Object数组  
    public synchronized Object[] toArray() {  
        return Arrays.copyOf(elementData, elementCount);  
    }  
 
    // 返回Vector的模板数组。所谓模板数组,即可以将T设为任意的数据类型  
    public synchronized <T> T[] toArray(T[] a) {  
        // 若数组a的大小 < Vector的元素个数;  
        // 则新建一个T[]数组,数组大小是“Vector的元素个数”,并将“Vector”全部拷贝到新数组中  
        if (a.length < elementCount)  
            return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());  
 
        // 若数组a的大小 >= Vector的元素个数;  
        // 则将Vector的全部元素都拷贝到数组a中。  
    System.arraycopy(elementData, 0, a, 0, elementCount);  
 
        if (a.length > elementCount)  
            a[elementCount] = null;  
 
        return a;  
    }  
 
    // 获取index位置的元素  
    public synchronized E get(int index) {  
        if (index >= elementCount)  
            throw new ArrayIndexOutOfBoundsException(index);  
 
        return (E)elementData[index];  
    }  
 
    // 设置index位置的值为element。并返回index位置的原始值  
    public synchronized E set(int index, E element) {  
        if (index >= elementCount)  
            throw new ArrayIndexOutOfBoundsException(index);  
 
        Object oldValue = elementData[index];  
        elementData[index] = element;  
        return (E)oldValue;  
    }  
 
    // 将“元素e”添加到Vector最后。  
    public synchronized boolean add(E e) {  
        modCount++;  
        ensureCapacityHelper(elementCount + 1);  
        elementData[elementCount++] = e;  
        return true;  
    }  
 
    // 删除Vector中的元素o  
    public boolean remove(Object o) {  
        return removeElement(o);  
    }  
 
    // 在index位置添加元素element  
    public void add(int index, E element) {  
        insertElementAt(element, index);  
    }  
 
    // 删除index位置的元素,并返回index位置的原始值  
    public synchronized E remove(int index) {  
        modCount++;  
        if (index >= elementCount)  
            throw new ArrayIndexOutOfBoundsException(index);  
        Object oldValue = elementData[index];  
 
        int numMoved = elementCount - index - 1;  
        if (numMoved > 0)  
            System.arraycopy(elementData, index+1, elementData, index,  
                     numMoved);  
        elementData[--elementCount] = null; // Let gc do its work  
 
        return (E)oldValue;  
    }  
 
    // 清空Vector  
    public void clear() {  
        removeAllElements();  
    }  
 
    // 返回Vector是否包含集合c  
    public synchronized boolean containsAll(Collection<?> c) {  
        return super.containsAll(c);  
    }  
 
    // 将集合c添加到Vector中  
    public synchronized boolean addAll(Collection<? extends E> c) {  
        modCount++;  
        Object[] a = c.toArray();  
        int numNew = a.length;  
        ensureCapacityHelper(elementCount + numNew);  
        // 将集合c的全部元素拷贝到数组elementData中  
        System.arraycopy(a, 0, elementData, elementCount, numNew);  
        elementCount += numNew;  
        return numNew != 0;  
    }  
 
    // 删除集合c的全部元素  
    public synchronized boolean removeAll(Collection<?> c) {  
        return super.removeAll(c);  
    }  
 
    // 删除“非集合c中的元素”  
    public synchronized boolean retainAll(Collection<?> c)  {  
        return super.retainAll(c);  
    }  
 
    // 从index位置开始,将集合c添加到Vector中  
    public synchronized boolean addAll(int index, Collection<? extends E> c) {  
        modCount++;  
        if (index < 0 || index > elementCount)  
            throw new ArrayIndexOutOfBoundsException(index);  
 
        Object[] a = c.toArray();  
        int numNew = a.length;  
        ensureCapacityHelper(elementCount + numNew);  
 
        int numMoved = elementCount - index;  
        if (numMoved > 0)  
        System.arraycopy(elementData, index, elementData, index + numNew, numMoved);  
 
        System.arraycopy(a, 0, elementData, index, numNew);  
        elementCount += numNew;  
        return numNew != 0;  
    }  
 
    // 返回两个对象是否相等  
    public synchronized boolean equals(Object o) {  
        return super.equals(o);  
    }  
 
    // 计算哈希值  
    public synchronized int hashCode() {  
        return super.hashCode();  
    }  
 
    // 调用父类的toString()  
    public synchronized String toString() {  
        return super.toString();  
    }  
 
    // 获取Vector中fromIndex(包括)到toIndex(不包括)的子集  
    public synchronized List<E> subList(int fromIndex, int toIndex) {  
        return Collections.synchronizedList(super.subList(fromIndex, toIndex), this);  
    }  
 
    // 删除Vector中fromIndex到toIndex的元素  
    protected synchronized void removeRange(int fromIndex, int toIndex) {  
        modCount++;  
        int numMoved = elementCount - toIndex;  
        System.arraycopy(elementData, toIndex, elementData, fromIndex,  
                         numMoved);  
 
        // Let gc do its work  
        int newElementCount = elementCount - (toIndex-fromIndex);  
        while (elementCount != newElementCount)  
            elementData[--elementCount] = null;  
    }  
 
    // java.io.Serializable的写入函数  
    private synchronized void writeObject(java.io.ObjectOutputStream s)  
        throws java.io.IOException {  
        s.defaultWriteObject();  
    }  
} 

Stack

Stack也是通过数组实现的,特性是先进后出
执行push时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。
执行peek时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。
执行pop时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除
其他的和Vector无不同,Vector有的,Stack都有。

最后是

CopyOnWriteArrayList

这是一个线程安全的ArrayList,用于并发环境,在很多方法中用了lock锁,防止多个写操作造成数据不一致问题。原理如下
CopyOnWriteArrayList对读操作,是不做处理,和普通的ArrayList性能一样。而在写操作(修改时),会先拷贝一份,实现新旧版本的分离,然后在拷贝的版本上进行修改操作,修改完后,将其更新至就版本中。
举一个添加元素的例子

public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock(); //加锁,防止多个写操作造成数据不一致问题;
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1); //构造一个新数组,并将旧的数据拷贝至新的数组中;
            newElements[len] = e;  //对新数组执行add操作;
            setArray(newElements);//将新数组更新至arrays
            return true;
        } finally {
            lock.unlock(); //释放锁;
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值