Collection 인터페이스 구조
ArrayList란?
객체 배열을 구현한 클래스이며 컬렉션 인터페이스와 그 하위 List 인터페이스를 구현하였습니다.
객체 순서를 기반으로 순차적으로 자료를 관리하는 프로그램을 구현할 때 사용합니다.
ArrayList 생성자
ArrayList는 3가지 형태의 생성자가 있다.
transient Object[] elementData;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 초기 크기를 갖는 생성자
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
// 기본 생성자
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 주어진 컬렉션이 저장된 생성자
public ArrayList(Collection<? extends E> c) {
...
}
- 기본생성자 사용 시 Object 타입의 객체 배열이지만 아직 초기화 하지 않은 상태에서 Object 타입의 객체 배열을 초기화 해주는 것을 볼 수 있습니다.
- 초기 크기를 갖는 생성자는 파라미터로 넘어온 값 만큼 Object 객체 배열을 선언해주는 것을 확인할 수 있습니다.
여기서 ArrayList는 객체 배열을 구현한 클래스라는 것을 알 수 있습니다.
add메서드
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
add 메서드에서는 선언한 객체 배열에 넘어온 실제 값을 배열에 넣어주고 size는 1추가 한것을 확인 할 수 있었습니다.
여기서 grow 메서드는 뭘까?
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
private Object[] grow() {
return grow(size + 1);
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
grow메서드는 배열을 복사하여 리턴해주는 것을 확인할 수 있었습니다.
처음 ArrayList를 선언하고 add를 해주었을 때는 newCapacity메서드에서 Math.max(DEFAULT_CAPACITY, minCapacity)를 통해 10을 반환하는 것을 확인 할 수 있습니다.
그렇기 때문에 ArrayList 선언 시 초기 크기를 지정해주지 않으면 기본 크기가 10이라는 것을 확인 할 수 있습니다.
Arrays.copy
add를 할 때 capacity를 넘기는 요청이 들어오면 grow 메서드에서 capacity를 더 늘린 배열을 복사하여 리턴을 해주는 방식입니다. 이것은 원래 데이터들을 모두 copy하여 집어 넣는 방식이기 때문에 애플리케이션 성능의 영향을 줄 수 있다고 생각합니다..
get메서드
E elementData(int index) {
return (E) elementData[index];
}
public E get(int index) {
Objects.checkIndex(index, size);
return elementData(index);
}
get 메서드는 인덱스를 가지고 데이터를 접근합니다. (인덱스를 통한 Random Access가 가능합니다.)
'JAVA' 카테고리의 다른 글
[JAVA] 추상클래스와 인터페이스 (0) | 2021.12.21 |
---|---|
[JAVA] 메서드 오버로딩(Method Overloading) 과 오버라이딩(Method Overriding) (0) | 2021.12.20 |
[JAVA] 메서드가 메모리에 저장되는 과정 (0) | 2021.12.18 |
[JAVA] 변수선언과 할당 (0) | 2021.12.16 |
[JAVA] 자바 구동방식 (0) | 2021.12.16 |