ArrayList的add(Object obj)和remove(Object obj)和remove(index)和get(index)的源碼分析

1.add(Object obj)


ArrayList list1 = new ArrayList();
		list1.add("a");
		list1.add(2);
		list1.add(3);
		list1.add(4);
		list1.add(5);	
		list1.add(6);	
		list1.add(7);	
		list1.add(8);	
		list1.add(9);	
		list1.add(10);
		list1.add(11);
		System.out.println(list1);
	
	public boolean add(E e) {//
		//size爲int類型的,初值爲默認類型.所以此時size的值爲0
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
	

		
	 private void ensureCapacityInternal(int minCapacity) {
		 //此時minCapacity=1
		 //elementData和DEFAULTCAPACITY_EMPTY_ELEMENTDATA都爲初值,所以相等
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
			//DEFAULT_CAPACITY:值爲10,
			//minCapacity:值爲1
			//DEFAULT_CAPACITY: private static final int DEFAULT_CAPACITY = 10;
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }




	  //傳入的值 minCapacity=10,
	  private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//位計數器,沒有實質的作用

		//elementData.length=0.
		//minCapacity=10
		//minCapacity - elementData.length > 0成立,
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
	
	//minCapacity=10
	 private void grow(int minCapacity) {
		//elementData.length = 0;故 oldCapacity=0
        int oldCapacity = elementData.length;
		//newCapacity值也爲0
        int newCapacity = oldCapacity + (oldCapacity >> 1);
		// newCapacity - minCapacity = -10 < 0成立,所以newCapacity = 10;
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
		//private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
		//newCapacity - MAX_ARRAY_SIZE > 0不成立.若newCapacity - MAX_ARRAY_SIZE > 0成立,會內存溢出
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //newCapacity = 10,所以此時的elementData長度爲10,數組的長度爲10,此時的elementData內的是個元素都爲null
        elementData = Arrays.copyOf(elementData, newCapacity);

		//這裏的方法就是數組擴容.此時數組的長度變爲10,之後在往上返回
    }

	//此時,add的方法源碼分析完畢,這是會把“a”這個元素添加到數組中,之後進行分析再添加一個元素

	
	//添加第二個元素時
	//若添加的元素的int類型,會把int類型裝箱,變爲Integer類型
	 public static Integer valueOf(int i) {
			if (i >= IntegerCache.low && i <= IntegerCache.high)
				return IntegerCache.cache[i + (-IntegerCache.low)];
			return new Integer(i);
		}

	
	 public boolean add(E e) {
		 //此時size爲1
        ensureCapacityInternal(size + 1);  // Increments modCount!!

        elementData[size++] = e;
        return true;
    }

	private void ensureCapacityInternal(int minCapacity) {
		//此時minCapacity=2
		//此時elementData=[a, null, null, null, null, null, null, null, null, null]
		//DEFAULTCAPACITY_EMPTY_ELEMENTDATA 還是爲0個長度
		//所以不成立
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
		//此時minCapacity=2
        ensureExplicitCapacity(minCapacity);
    }
	
	 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

		//minCapacity = 2,elementData.length > 0不成立,所以,數組的不擴容
        
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//數組的擴容
    }

    //當數組的元素個數小於等於10時,數組都不擴容
	.
	.
	.
	.
	.
	.
	//當添加到11個元素時
	
	//第11個元素還未int類型,所以進行裝箱
	 public static Integer valueOf(int i) {
			if (i >= IntegerCache.low && i <= IntegerCache.high)
				return IntegerCache.cache[i + (-IntegerCache.low)];
			return new Integer(i);
		}

	//添加元素
	 public boolean add(E e) {
		 //此時size爲10
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

	private void ensureCapacityInternal(int minCapacity) {
		//minCapacity = 11

		//elementData = [a, 2, 3, 4, 5, 6, 7, 8, 9, 10]
		//DEFAULTCAPACITY_EMPTY_ELEMENTDATA = []
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
		
        ensureExplicitCapacity(minCapacity);
    }
	
	private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

		//minCapacity:11
		//elementData.length = 10
		//此時成立,執行數組的擴容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
	
	//數組擴容
	 private void grow(int minCapacity) {
       //minCapacity = 11
	   //elementData.length = 10
        int oldCapacity = elementData.length;
		//oldCapacity >> 1: 右移1位,所以爲5
		//newCapacity = 15
        int newCapacity = oldCapacity + (oldCapacity >> 1);
		//newCapacity = 15   minCapacity = 11,不成立
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
		//不成立
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //此時新的數組的長度爲15,數組長度變大
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

	//新數組的長度爲15



	//綜上分析:當初始化ArrayList時,底層數組的長度爲0《當向裏面添加第一個元素時,數組的長度變爲10,當
	//數組長度大於10時,數組會進行擴容.經分析,每次擴容新的長度爲原來的1.5倍  所以第二次擴容爲15,第三次爲22
	//到此,ArrayList的add(Object) 源碼分析完

2.get(index)

//構造器ArrayList()
   public ArrayList() {
		//1.elementData是一個Object[]的數組.
		//2.private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};是一個空的數組
       this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;													
    }

		ArrayList list1 = new ArrayList();
		list1.add("a");
		list1.add(2);
		list1.add(3);
		list1.add(4);
		list1.add(5);	
		list1.add(6);	
		list1.add(7);	
		list1.add(8);	
		list1.add(9);	
		list1.add(10);
		list1.add(11);
		
		Object value = list1.get(2);
		System.out.println(value);

//1.get(index)

	public E get(int index) {
		//檢查下標是否越界,否則會拋出數組下標越界異常
        rangeCheck(index);

		//返回下標爲index的元素
        return elementData(index);
    }

	 private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
	
	//返回下標爲index的元素
	E elementData(int index) {
        return (E) elementData[index];
    }



3..remove(index),返回值爲Object類型


//構造器ArrayList()
   public ArrayList() {
		//1.elementData是一個Object[]的數組.
		//2.private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};是一個空的數組
       this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;													
    }


//1.remove(index),返回值爲Object類型


		public E remove(int index) {
				//index:傳入要刪除元素的位置,假設下標爲2,即index=2

				//檢查index是否越界
				rangeCheck(index);

				modCount++;//計數器

				//得到下標爲index的元素,值爲oldValue
				E oldValue = elementData(index);

				//此時數組的長度爲11,size=11,index=2,所以numMoved=8
				int numMoved = size - index - 1;

				 //arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 
				 //從指定源數組中複製一個數組,複製從指定的位置開始,到目標數組的指定位置結束。
				 //第一個elementData:原數組
				 //第二個elementData:目標數組
				 //源數組中位置在 srcPos 到 srcPos+length-1 之間的組件被分別複製到目標數組中的 destPos 到 destPos+length-1 位置。 
				 //public static void arraycopy(Object src,int srcPos,Object dest,int destPos, int length)
				if (numMoved > 0)
					System.arraycopy(elementData, index+1, elementData, index,
									 numMoved);
				//此時最後的一個元素設爲nul,這是數組的長度就減1了
				elementData[--size] = null; // clear to let GC do its work

				//返回刪除的元素
				return oldValue;
			}

			
			 private void rangeCheck(int index) {
				 //當index大於數組的長度時,會拋出數組下標越界異常.
				if (index >= size)
				throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
			 }

4.remove(Object obj),當遇到要刪除的對象爲int類型時,要把該int類型的值進行裝箱,變爲Integer類型

//構造器ArrayList()
   public ArrayList() {
		//1.elementData是一個Object[]的數組.
		//2.private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};是一個空的數組
       this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;													
    }

		ArrayList list1 = new ArrayList();
		list1.add("a");
		list1.add(2);
		list1.add(3);
		list1.add(4);
		list1.add(5);	
		list1.add(6);	
		list1.add(7);	
		list1.add(8);	
		list1.add(9);	
		list1.add(10);
		list1.add(11);
		
		Object value =  list1.remove(new Integer(2));
		System.out.println(value);



//1.remove(Object obj),當遇到要刪除的對象爲int類型時,
//要把該int類型的值進行裝箱,變爲Integer類型

  public boolean remove(Object o) {
		
		//當傳入的對象爲null值是.
        if (o == null) {
			//遍歷數組elementData
            for (int index = 0; index < size; index++)
				//如果遍歷到值爲null的時
                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;
		  //arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 
		 //從指定源數組中複製一個數組,複製從指定的位置開始,到目標數組的指定位置結束。
		 //第一個elementData:原數組
		 //第二個elementData:目標數組
		 //源數組中位置在 srcPos 到 srcPos+length-1 之間的組件被分別複製到目標數組中的 destPos 到 destPos+length-1 位置。 
		 //public static void arraycopy(Object src,int srcPos,Object dest,int destPos, int length)
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
		//最後一個位置上的元素設置爲null
        elementData[--size] = null; // clear to let GC do its work
    }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章