ArrayList는 List 인터페이스를 구현하기 때문에 데이터의 저장순서가 유지되고 중복을 허용한다는 특징을 갖는다. 기존의 Vector를 개선한 것으로 Vector와 구현원기와 기능적인 측면에서 동일하다고 볼 수 있다. ArrayList는 Object 배열을 이용해서 데이터를 순차적으로 저장한다. 배열에 더 이상 저장할 공간이 없으면 보다 큰 새로운 배열을 생성해서 기존의 배열에 저장된 내용을 새로운 배열로 복사한 다음에 저장한다.
method들은 직접 api를 찾아서 확인할 수 있다고 믿으므로 생략하겠다.
ArrayList를 분석하기 위해 Vector 클래스의 실제 코드를 바탕으로 이해하기 쉽게 재구성 해보자. 위에서도 언급했듯이 ArrayList는 Vector를 개선한 것이므로 코드 자체는 별 차이가 없다.
public class MyVector implements List{
object[] data = null; //객체를 담기 위한 객체 배열
int capacity = 0; //배열의 최대 크기
int size = 0; //배열에 현재 데이터가 담긴 크기
public MyVector(int capacity){
if(capacity < 0)
throw new IllegalArgumentException("유효하지 않은 값입니다. :"+ capacity);
this.capacity = capacity;
data = new Object[capacity];
}
public MyVector(){
this(10); //크기가 지정되지 않으면 10으로 자동 생성
}
public void ensureCapacity(int minCapacity){
if(minCapacity - data.length > 0) setCapacity(minCapacity);
}
public boolean add(Object obj){
//새로운 객체를 저장하기 위해 저장할 공간을 확보
ensureCapacity(size+1);
data[size++] = obj;
return true;
}
public Object get(int index){
if(index < 0 || index >= size) throw new IndexOutOfBoundsException("범위를 벗어났습니다.");
return data[index];
}
public Object remove(int index){
Object oldObj = null;
if(index < 0 || index >= size)
throw new IndexOutOfBoundsException("범위를 벗어났습니다.");
oldObj = data[index];
if(index != size-1)
System.arraycopy(data, index+1, data, index, size - index-1);
data[size-1] = null;
size--;
return oldObj;
}
public boolean remove(Object obj){
for(int i=0; i<size; i++){
if(obj.equals(data[i])){
remove(i);
return true;
}
}
return false;
}
public void trimToSize(){
setCapacity(size);
}
private void setCapacity(int capacity){
if(this.capacity==capacity) return; //크기가 동일하면 실행하지 않음
Object[] tmp = new Object[capacity];
System.arraycopy(data, 0, tmp, 0, size);
data = tmp;
this.capacity = capacity;
}
public void clear(){
for(int i=0; i<size; i++){
data[i] = null;
}
size = 0;
}
public Object[] toArray(){
Object[] result = new Object[size];
System.arraycopy(data, 0, result, 0, size);
return result;
}
public boolean isEmpty(){
return size==0;
}
public int capacity(){
return capacity;
}
public int size(){
return size;
}
... 이 외 List 인터페이스로부터 상속받은 method
}
위 코드가 Vector class를 구현한 코드이다. 평소 ArrayList를 사용하며 add가 어떻게 되어지고 remove가 어떻게 동작하는지 궁금했을 분들에게 도움이 될 것 같다. 간략하게 설명하면 add와 remove 모두 새로운 배열을 만들고 해당 배열에 복사를 한다는 개념을 알고 있으면 될것 같다!
만약 이렇게 Java의 기본 제공 class들을 분석해보고 싶다면 설치된 java 폴더내 src.zip의 압축을 푼 뒤 패키지에 맞게 찾아보면 해당 코드를 실제로 볼 수 있다. 해당 코드는 java 전문가들이 풀어놓은 코드이기 때문에 코드를 분석해보면 실력 향상에 매우 도움이 된다.