Java ArrayList source code analysis (help to understand the data structure)

arraylist source code analysis

1. Introduction Array

Array data structure is a very basic configuration, many programming languages ​​are built array, similar to the data structure in linear form

It will be divided in java when creating an array in memory a contiguous memory, and when data will be entered when data is stored in contiguous order in this memory. When the data needs to be read in the array, the array need to provide an index, then the inner array according to the index

Data stored in the taken out, returned to the reader. In Java, not all data can be stored in an array, only the same type of data can only be stored in the array together.

  

 

 

 Because the data is stored in the array sequentially stored in memory for storing data is continuous, so he is characterized by: addressing data easier to read, insert and delete more difficult.

 

Parameterized constructor

public the ArrayList ( int initialCapacity) {
         IF (initialCapacity> 0 ) { 
       // create an array of given length
the this .elementData = new new Object [initialCapacity]; } the else IF (initialCapacity == 0 ) {
       // empty array
the this .elementData = EMPTY_ELEMENTDATA ; } the else { the throw new new an IllegalArgumentException ( "Illegal Capacity:" + initialCapacity);} // if neither greater than zero, not less than zero, the error will be thrown }

 

Empty constructor parameters

    public the ArrayList () {
         the this .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // assigned to a member variable 
    } 
  Private static Final Object [] = {} DEFAULTCAPACITY EMPTY elementData; // constructor creates an empty reference array is an empty

 

Much below this use, to be able to read

public the ArrayList (Collection <? the extends E> C) { 
        elementData of = c.toArray () ; // put Collection this collection has become an array, the array of the current passed elementData of 
     // is greater than 0, it copies the array
IF (( = elementData.length size)! = 0 ) { // determine the length of the current elementData array, if not equal to 0 IF (elementData.getClass ()! = Object []. class ) // Object is determined whether the type is an array type, if this type is not elementData = Arrays.copyOf (elementData, size, Object []. class ); . // copy of an array, then the length, and the Object [] class pass into the array, and then generates a elementData array
     // is not greater than 0 , on an empty copy of }
the else { // Replace with empty Array. The this .elementData = EMPTY_ELEMENTDATA; // set to an empty array } }

 

 

 Adding elements

public  Boolean the Add (E E) { 
     detect the need for expansion ¹ under ensureCapacityInternal ( be minCapacity: size
+. 1); // size is the number of data currently stored
     array assignment
elementData of [size ++] = E; return to true ; }

 

 Inlet expansion method, computing capacity

Private  void  ¹ on ensureCapacityInternal ( int be minCapacity) { // be minCapacity minimum time is passed after the + 1'd 
³ under the ensureExplicitCapacity ( lower ² calculateCapacity (elementData of, be minCapacity)); // computing capacity, passing elementData of an array, re-transmission of a minimum capacity minCapacity

 

Calculating the minimum displacement

Private  static  int  ² on calculateCapacity (Object [] elementData, int be minCapacity) {
 // If elementData empty 
IF (elementData == EMPTY defaul TCAPACITY the EL EMENTDAT) |
 // returns a default or minCapacity, and finally returns the largest 
return max the Math (DEFAULT_CAPACIT be minCapacity);. 
 // is not empty, the value is returned size + 1, 
return be minCapacity; 
}

 

 

private void 上上³ensureExplicitCapacity(int minCapacityp{
//只要发生修改就+1 modCount
++;
//是否满足扩容的条件 最小容量(当前数组存值得容量?) - object数组的长度
if(minCapacity-elementData. length〉0)//elementData.lenth=10 (默认容量为10)
下¹grow(minCapacity);

 

 数组扩容方法

private void 上¹grow(int minCapacity){
   //计算当前数组容量,也就是老的容量
   int oldCapacity=elementData. length;
   //新的数组容量 = 老容量 + 老容量/2 (老容量的1.5倍)

  int newCapacity=oldCapacity+(oldCapacity >>1); >>1 除二

     // oldcapacity=10
    // oldcapacity >>1
    // 0000 1010 >> 1
    // 0000 0101 = 5

    //判断新的数组容量-之前最小容量

   if(newCapacity-minCapacity<0)
      newCapacity=minCapacity;
   if (newCapacity - MAX_ARRAY_SIZE>0) //MAX_ARRAY_SIZE:值特别大,如果新的数组比它还大,就越界了,或者直接返回最大长度       newCapacity = hugeCapacity(minCapacity);
   elementData=Arrays. copyof(elementData, newCapacity);

 

private static int 上上上³calculateCapacity(Object[] elementData, int minCapacity){
//如果elementData是空的
if(elementData==DEFAUL TCAPACITY EMPTY EL EMENTDAT)|
//返回一个默认或者minCapacity,最后是返回其中最大的 return Math. max(DEFAULT_CAPACIT minCapacity);
//不是空,就返回size+1的值
return minCapacity; }

 

    public void add(int index, E element) {
     判断下标是否越界 rangeCheckForAdd(index);      检测是否需要扩容 ensureCapacityInternal(size
+ 1);
      把index之后的所有元素向后移动一位
System.arraycopy(elementData, index, elementData, index + 1, size - index);
     
将index位置覆盖上新值
elementData[index] = element; size++; }
private void rangeCheckForAdd(int index){
if(index>size || index<0)
throw new IndexOutofBoundsException(outofBoundsMsg(index));

 

System.arraycopy(elementData, index, elementData, index + 1,size - index); 举例

int
[] elementData = new int[10]; for(int i=0;i<5;i++){ //数组的下标 0,1,2,3,4 elementData[i]=i+1; //数组的值 1,2,3,4,5 System. out. println("=="+Arrays. toString(elementData)); int size=5; int index=1; //插入数组下标位置 System. arraycopy(elementData, index, elementData, destPos: index+1, length: size-index); 原数组,插入指定的位置,又指定的数组,指定的位置为当前位置+1,到5-1=4的位置 >>从插入位置往后算 System. out. println("--"+Arrays. toString(elementData));

打印结果

 ==  [1,2,3,4,5,0,0,0,0,0]
 一  [1,2,2,3,4,5,0,0,0,0]  2:是要插入的数值

 

 

 

删除方法

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; // clear to let GC do its work

        return oldValue;
    }

 

 

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

 

Guess you like

Origin www.cnblogs.com/xiaozhongfeixiang/p/11514674.html