자바의 ArrayList 소스 코드 분석 (데이터 구조를 이해하는 데 도움이)

ArrayList의 소스 코드 분석

1. 소개 어레이

배열은 직선 형태의 데이터 구조와 유사한 매우 기본적인 구성, 많은 프로그래밍 언어가 내장되어 배열입니다

메모리 어레이 인접 메모리를 만들 때 자바으로 분할되며,이 데이터를 메모리에 연속적 순서로 저장 될 때 데이터가 입력 될 때. 데이터 어레이 판독 될 필요가있을 때, 어레이 내부 배열 인덱스에 따라 다음 인덱스를 제공해야

꺼낸에 저장된 데이터는, 독자에게 돌아왔다. Java에서는, 모든 데이터가 어레이에 저장 될 수없는 데이터의 동일한 유형은 함께 배열에 저장 될 수있다.

  

 

 

 하여 데이터가 데이터를 연속 저장하는 메모리에 기억 된 배열을 순차적으로 저장되고, 그래서 그는 특징 이유는 판독 데이터를 쉽게 어드레싱 삽입 어려워 삭제.

 

매개 변수화 된 생성자

공용 ArrayList를 ( INT의 파라미터 : initialCapacity) {
         IF (파라미터 : initialCapacity> 0 ) { 
       // 특정 길이의 배열을 생성
이 본 .elementData = 새로운 새로운 개체 [파라미터 : initialCapacity] } 다른 IF (파라미터 : initialCapacity == 0 ) {
       // 빈 배열
이 본 .elementData = EMPTY_ELEMENTDATA ; } 다른 { 던져 새로운 새로운 는 IllegalArgumentException ( "잘못된 용량 :"+ 파라미터 : initialCapacity);} // 어느 쪽도 제로보다 큰, 이하 0보다 오류가 발생되지 않습니다 경우 }

 

빈 생성자 매개 변수

    공용 ArrayList를 () {
         이 본 .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // 멤버 변수에 할당 
    } 
  개인 정적 최종 개체 [] = {} DEFAULTCAPACITY으로부터 elementData EMPTY는; // 생성자 빈 레퍼런스 어레이가 비어 생성

 

대부분이 사용 아래에 읽을 수 있도록

공용 ArrayList를는 (수집 <? 는 연장 E> C) { 
        의으로부터 elementData = c.toArray는 () ; // 컬렉션 배열되었다 컬렉션을 넣어, 현재의 배열 중으로부터 elementData 통과 
     그것을 복사 배열을 0보다 큰 //
IF (( = elementData.length 사이즈)! = 0 ) { //가 현재으로부터 elementData 어레이의 길이를 결정 같지 0 IF (elementData.getClass ()! = 개체 []. 등급 ) // 개체는 유형이 어레이 형이 경우인지를 판단 이 유형은 아니다 으로부터 elementData (.으로부터 elementData, 크기는, [] 오브젝트 = Arrays.copyOf이 클래스 ) // 다음 배열 복사 길이 및 객체 [] 클래스 어레이로 전달하고,이어서으로부터 elementData 어레이를 생성한다.
     // 0보다 크지 의 빈 복사본 }
다른 { // 빈 배열 교체. 이 본 .elementData = EMPTY_ELEMENTDATA 단계; 빈 배열로 설정 // } }

 

 

 요소 추가

공개  부울 추가 (E E)는 { 
     확장이 필요한지 여부를 확인 하에 ¹ ensureCapacityInternal ( minCapacity가 될 : 크기
. + 1); // 크기는 현재 저장된 데이터의 개수를
     어레이 할당
으로부터 elementData [크기 ++ = 중 , E는 반환 ; }

 

 입구 확장 방법 컴퓨팅 용량

전용  공간  에 ¹ ensureCapacityInternal은 ( INT는 minCapacity가 될) { minCapacity가 최소 시간은 +1 경과하다 // 
언더 ³ ensureExplicitCapacity ( 저급 ² calculateCapacity 의 (으로부터 elementData 수 minCapacity가)); // 컴퓨팅 용량 어레이로으로부터 elementData 건네 재송 최소 용량의 minCapacity가

 

최소 변위를 계산

개인  정적  INT  ²에 calculateCapacity (객체 []으로부터 elementData는, INT가 될 minCapacity가) {
 // 으로부터 elementData이 비어있는 경우 
IF (으로부터 elementData는 == EMPTY가 기본으로의 TCAPACITY는 EL EMENTDAT은) |
 //은 기본 또는 minCapacity가를 반환하고, 마지막으로 가장 큰 반환 
반환 최대 수학 (DEFAULT_CAPACIT에게 minCapacity가 될); 
 //이 값은 크기 + 1이 리턴되며, 비어 있지 
복귀 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;
    }

 

추천

출처www.cnblogs.com/xiaozhongfeixiang/p/11514674.html