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