JDK源码 – 容器 – Vector

JDK源码 – 容器 – Vector

本章介绍的是Vector,主要学习方式是解读源码,将底层实现暴露给阅读者,这样学习更简单明了

简介

  • Vector 是矢量队列,它是JDK1.0版本添加的类。 继承于AbstractList,实现了List,RandomAccess, Cloneable这些接口。
  • Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。 Vector 实现了RandmoAccess接口,即提供了随机访问功能
  • Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
  • Vector实现了Cloneable接口,即实现clone()函数。它能被克隆。

构造函数

Vector共有4个构造函数

默认构造函数
  • Vector() //默认长度为10
  • Vector(int capacity, int capacityIncrement) //初始化默认长度,扩展增额度
  • Vector(int initialCapacity) //初始化默认长度
  • Vector(Collection< ? extends E> c)//赋值集合

capacity是Vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。

数据结构

Vector的数据结构和ArrayList差不多,它包含了3个成员变量:elementData , elementCount, capacityIncrement。

  1. elementData
    是"Object[]类型的数组",它保存了添加到Vector中的元素。随着Vector中元素的增加,Vector的容量也会动态增长,capacityIncrement是与容量增长相关的增长系数,具体的增长方式,请参考源码分析中的ensureCapacity()函数。
  2. elementCount 是动态数组的实际大小。.
  3. capacityIncrement 是动态数组的增长系数。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时>,增加的大小都是capacityIncrement。

总结

  1. Vector实际上是通过一个数组去保存数据的。 当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。
  2. 当Vector容量不足以容纳全部元素时,Vector的容量会增加。 若容量增加系数

    0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。

  3. Vector的克隆函数,即是将全部元素克隆到一个数组中。
为什么Vector线程安全

因为在底层实现上进行了加锁, 缺点:效率低

源码阅读

package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
//构造函数
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
	protected Object[] elementData;  
	protected int elementCount;   
	protected int capacityIncrement;   
	private static final long serialVersionUID = -2767605614048989439L;   
	public Vector(int initialCapacity, int capacityIncrement) {
        super();     
          if (initialCapacity < 0){
		throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);     
		this.elementData = new Object[initialCapacity];   
		this.capacityIncrement = capacityIncrement;    
		}
//构造函数
	public Vector(int initialCapacity) {
	        this(initialCapacity, 0);   
         }
//构造函数
	public Vector() {
	        this(10);   
        }
//构造函数
	public Vector(Collection<? extends E> c) {
	        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);  
                 }

    //拷贝数组
	public synchronized void copyInto(Object[] anArray) {
		System.arraycopy(elementData, 0, anArray, 0, elementCount);   
         }

    //去除多余空位
	public synchronized void trimToSize() {
        modCount++;       
	if (elementCount < oldCapacity) {
            elementData = Arrays.copyOf(elementData, elementCount);       
            }
    }

    //确保性能
	public synchronized void ensureCapacity(int minCapacity) {
        if (minCapacity > 0) {
            modCount++;           
	}
    }

     // overflow-conscious code   
   private void ensureCapacityHelper(int minCapacity) {
        
        if (minCapacity - elementData.length > 0)
}

    //自动扩容
  private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;   
  private void grow(int minCapacity) {
        // overflow-conscious code       
	int oldCapacity = elementData.length;   
	int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);      
	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;   
            }
//设置容量长度
	 public synchronized void setSize(int newSize) {
	        modCount++;       
	        if (newSize > elementCount) {
	            ensureCapacityHelper(newSize);      
	             } else {
	            for (int i = newSize ; i < elementCount ; i++) {
	                elementData[i] = null;         
	                  }
	        }
	        elementCount = newSize;  
         }
//得到容量长度
     public synchronized int capacity() {
        return elementData.length;  
         }
//得到容量
	public synchronized int size() {
        return elementCount;  
         }

//是否是空
	public synchronized boolean isEmpty() {
        return elementCount == 0;   
        }
//节点集合
 public Enumeration<E> elements() {
        return new Enumeration<E>() {
            int count = 0;           
            public boolean hasMoreElements() {
	}

            public E nextElement() {
                synchronized (Vector.this) {
                    if (count < elementCount) {
                        return elementData(count++);                    
                        }
                }
	}
     };   
 }

//包含
 public boolean contains(Object o) {
        return indexOf(o, 0) >= 0;  
         }

//元素索引位置
  public int indexOf(Object o) {
        return indexOf(o, 0);    
        }

  public synchronized int indexOf(Object o, int index) {
        if (o == null) {
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;      
                     } else {
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;      
                     }
        return -1;  
          }
//元素索引最后位置
  public synchronized int lastIndexOf(Object o) {
        return lastIndexOf(o, elementCount-1);    
        }

  public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);    
	    if (o == null) {
            for (int i = index; i >= 0; i--)
                if (elementData[i]==null)
                    return i;       } else {
            for (int i = index; i >= 0; i--)
                if (o.equals(elementData[i]))
		    }
	        return -1;   
	         }

//索引位置元素
  public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);     
               }
        return elementData(index);   
        }


  public synchronized E firstElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();     
               }
        return elementData(0);   
        }

  public synchronized E lastElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();        
            }
        return elementData(elementCount - 1);    
        }

   public synchronized void setElementAt(E obj, int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);        
            }
        elementData[index] = obj;
           }

 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 */ 
             }

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


  public synchronized void addElement(E obj) {
             modCount++;     
             ensureCapacityHelper(elementCount + 1);      
             elementData[elementCount++] = obj;  
               }


  public synchronized boolean removeElement(Object obj) {
	       modCount++;                                                                
	       int i = indexOf(obj);    
	       if (i >= 0) {
	               removeElementAt(i);       
	               return true;        
               }
	        return false;  
          }

  public synchronized void removeAllElements() {
	modCount++;    
	for (int i = 0; i < elementCount; i++)
		elementData[i] = null;   
		elementCount = 0; 
	   }

  public synchronized Object clone() {
        try {
            @SuppressWarnings("unchecked")
                Vector<E> v = (Vector<E>) super.clone();     
		v.elementData = Arrays.copyOf(elementData, elementCount);        
		v.modCount = 0;        
		return v;     
		  } catch (CloneNotSupportedException e) {
             throw new InternalError(e);      
               }
    }

//转化成数组
  public synchronized Object[] toArray() {
        return Arrays.copyOf(elementData, elementCount);    
        }

  @SuppressWarnings("unchecked")
    public synchronized <T> T[] toArray(T[] a) {
        if (a.length < elementCount)
	return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());        
	System.arraycopy(elementData, 0, a, 0, elementCount);      
	if (a.length > elementCount)
	a[elementCount] = null;  
	return a; 
	   }

 
 @SuppressWarnings("unchecked")
	E elementData(int index) {
	        return (E) elementData[index];  
	         }


  public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);      
              return elementData(index);  
                }

  public synchronized E set(int index, E element) {
        if (index >= elementCount)
	         throw new ArrayIndexOutOfBoundsException(index);    
		 E oldValue = elementData(index);    
		 elementData[index] = element;   
		 return oldValue;   
		  }


  public synchronized boolean add(E e) {
        modCount++;     
	ensureCapacityHelper(elementCount + 1);    
	elementData[elementCount++] = e;     
	return true;   
	 }

  
 public boolean remove(Object o) {
        return removeElement(o);  
          }

 public void add(int index, E element) {
        insertElementAt(element, index);  
         }

    
 public synchronized E remove(int index) {
        modCount++;        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);        E 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 oldValue;    }


 public void clear() {
        removeAllElements();    }


  public synchronized boolean containsAll(Collection<?> c) {
        return super.containsAll(c);    }

  public synchronized boolean addAll(Collection<? extends E> c) {
        modCount++;        Object[] a = c.toArray();        int numNew = a.length;        ensureCapacityHelper(elementCount + numNew);        System.arraycopy(a, 0, elementData, elementCount, numNew);        elementCount += numNew;        return numNew != 0;    }


  public synchronized boolean removeAll(Collection<?> c) {
        return super.removeAll(c);    }

   public synchronized boolean retainAll(Collection<?> c) {
        return super.retainAll(c);    }

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

 
 public synchronized String toString() {
        return super.toString();    }


   public synchronized List<E> subList(int fromIndex, int toIndex) {
        return 
Collections.synchronizedList(super.subList(fromIndex, toIndex),                                            this);    
}

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


  private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        final java.io.ObjectOutputStream.PutField fields = s.putFields();        final Object[] data;        synchronized (this) {
            fields.put("capacityIncrement", capacityIncrement);            fields.put("elementCount", elementCount);            data = elementData.clone();        }
        fields.put("elementData", data);        s.writeFields();    }


   public synchronized ListIterator<E> listIterator(int index) {
        if (index < 0 || index > elementCount)
            throw new IndexOutOfBoundsException("Index: "+index);        return new ListItr(index);    }

 public synchronized ListIterator<E> listIterator() {
        return new ListItr(0);    }

  public synchronized Iterator<E> iterator() {
        return new Itr();    }

  private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return        
int lastRet = -1; // index of last element returned; -1 if no such       
 int expectedModCount = modCount;     
   public boolean hasNext() {

     return cursor != elementCount;        }

        public E next() {
            synchronized (Vector.this) {
                checkForComodification();        
        int i = cursor;         
       if (i >= elementCount)
                    throw new NoSuchElementException();     
           cursor = i + 1;        
        return elementData(lastRet = i);            }
        }

        public void remove() {
            if (lastRet == -1)
                throw new IllegalStateException();            synchronized (Vector.this) {
                checkForComodification();                Vector.this.remove(lastRet);                expectedModCount = modCount;            }
            cursor = lastRet;            lastRet = -1;        }

        @Override        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);            synchronized (Vector.this) {
                final int size = elementCount;                int i = cursor;                if (i >= size) {
                    return;                }
        @SuppressWarnings("unchecked")
                final E[] elementData = (E[]) Vector.this.elementData;                if (i >= elementData.length) {
                    throw new ConcurrentModificationException();                }
                while (i != size && modCount == expectedModCount) {
                    action.accept(elementData[i++]);                }
                // update once at end of iteration to reduce heap write traffic                cursor = i;                lastRet = i - 1;                checkForComodification();            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();        }
    }

 final class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();            cursor = index;        }

        public boolean hasPrevious() {
            return cursor != 0;        }

        public int nextIndex() {
            return cursor;        }

        public int previousIndex() {
            return cursor - 1;        }

        public E previous() {
            synchronized (Vector.this) {
                checkForComodification();                int i = cursor - 1;                if (i < 0)
                    throw new NoSuchElementException();                cursor = i;                return elementData(lastRet = i);            }
        }

        public void set(E e) {
            if (lastRet == -1)
                throw new IllegalStateException();            synchronized (Vector.this) {
                checkForComodification();                Vector.this.set(lastRet, e);            }
        }

        public void add(E e) {
            int i = cursor;            synchronized (Vector.this) {
                checkForComodification();                Vector.this.add(i, e);                expectedModCount = modCount;            }
            cursor = i + 1;            lastRet = -1;        }
    }

    @Override    public synchronized void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);        final int expectedModCount = modCount;        @SuppressWarnings("unchecked")
        final E[] elementData = (E[]) this.elementData;        final int elementCount = this.elementCount;        for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
            action.accept(elementData[i]);        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();        }
    }

    @Override    @SuppressWarnings("unchecked")
    public synchronized boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);        // figure out which elements are to be removed       // any exception thrown from the filter predicate at this stage       // will leave the collection unmodified        int removeCount = 0;        final int size = elementCount;        final BitSet removeSet = new BitSet(size);        final int expectedModCount = modCount;        for (int i=0; modCount == expectedModCount && i < size; i++) {
            @SuppressWarnings("unchecked")
            final E element = (E) elementData[i];            if (filter.test(element)) {
                removeSet.set(i);                removeCount++;            }
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();        }

        // shift surviving elements left over the spaces left by removed elements        final boolean anyToRemove = removeCount > 0;        if (anyToRemove) {
            final int newSize = size - removeCount;            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
                i = removeSet.nextClearBit(i);                elementData[j] = elementData[i];            }
            for (int k=newSize; k < size; k++) {
                elementData[k] = null;  // Let gc do its work            }
            elementCount = newSize;            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();            }
            modCount++;        }

        return anyToRemove;    }

    @Override    @SuppressWarnings("unchecked")
    public synchronized void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);        final int expectedModCount = modCount;        final int size = elementCount;        for (int i=0; modCount == expectedModCount && i < size; i++) {
            elementData[i] = operator.apply((E) elementData[i]);        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();        }
        modCount++;    }

    @SuppressWarnings("unchecked")
    @Override    public synchronized void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;        Arrays.sort((E[]) elementData, 0, elementCount, c);        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();        }
        modCount++;    }


   @Override    public Spliterator<E> spliterator() {
        return new VectorSpliterator<>(this, null, 0, -1, 0);    }

  static final class VectorSpliterator<E> implements Spliterator<E> {
        private final Vector<E> list;        private Object[] array;        private int index; // current index, modified on advance/split        private int fence; // -1 until used; then one 
    VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,                          int expectedModCount) {
            this.list = list;            this.array = array;            this.index = origin;            this.fence = fence;            this.expectedModCount = expectedModCount;        }

        private int getFence() { // initialize on first use            int hi;            if ((hi = fence) < 0) {
                synchronized(list) {
                    array = list.elementData;                    expectedModCount = list.modCount;                    hi = fence = list.elementCount;                }
            }
            return hi;        }

        public Spliterator<E> trySplit() {
            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;            return (lo >= mid) ? null :
                new VectorSpliterator<E>(list, array, lo, index = mid,                                         expectedModCount);        }

        @SuppressWarnings("unchecked")
        public boolean tryAdvance(Consumer<? super E> action) {
            int i;            if (action == null)
                throw new NullPointerException();            if (getFence() > (i = index)) {
                index = i + 1;                action.accept((E)array[i]);                if (list.modCount != expectedModCount)
                    throw new ConcurrentModificationException();               return true;            }
            return false;        }

        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> action) {
            int i, hi; // hoist accesses and checks from loop            Vector<E> lst; Object[] a;            if (action == null)
                throw new NullPointerException();            if ((lst = list) != null) {
                if ((hi = fence) < 0) {
                    synchronized(lst) {
                        expectedModCount = lst.modCount;                        a = array = lst.elementData;                        hi = fence = lst.elementCount;                    }
                }
                else                    a = array;                if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
                    while (i < hi)
                        action.accept((E) a[i++]);                    if (lst.modCount == expectedModCount)
                        return;                }
            }
            throw new ConcurrentModificationException();        }

        public long estimateSize() {
            return (long) (getFence() - index);        }

        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值