HomeBlogGuestbookLab 

JDM's Blog

온갖 테스트 결과가 기록되는 이곳은 JDM's Blog입니다. :3

자바 ArrayList(Java ArrayList)

지난번 포스팅인 자바 벡터(Java Vector)에 이어서 이번엔 ArrayList에 대해서 알아보고자 합니다.

Initialize ArrayList

ArrayList는 기본적으로 다음과 같이 초기화를 할 수 있습니다.

/* initialize ArrayList */
// (1)
// 기본 크기는 10으로 지정된다.
ArrayList<String> al = new ArrayList<String>();

// (2)
// 크기가 10인 배열 생성
// 요소 삽입으로 배열 크기 초과시 초기 지정값 만큼 커진다.
ArrayList<String> al2 = new ArrayList<String>(10);

// (3)
// Object로 선언 후 실제 요소들을 다양하게 삽입
ArrayList<Object> al3 = new ArrayList<Object>(10);
al3.add(1);
al3.add("1");

ArrayList도 벡터와 마찬가지로 데이터 저장 용도 멤버 변수인 Object[]를 가지고 있습니다. Object로 선언 뒤에 다양한 객체를 삽입 할 수 있긴 합니다.

Methods

벡터에서는 .add() 메소드에 synchronized 키워드가 있었습니다. 하지만 ArrayList의 메소드에는 그런 키워드가 존재하지 않습니다.

public boolean add(E e)

눈에 불을 키고 찾아봐도 synchronized 키워드가 붙은 메소드가 없네요. ArrayList와 벡터의 결정적 차이는 메소드의 synchronized 키워드 여부입니다. 다른 말로 바꿔보자면 동기화를 하는 벡터와 동기화가 없는 ArrayList가 되겠네요.

[TIP] 다음과 같은 방식으로 동기화가 되는 ArrayList를 생성 할 수 있습니다.

List ary = Collections.synchronizedList(new ArrayList<String>());

grow Size

ArrayList에서 크기를 초과하는 요소 삽입시에 하는 액션은 벡터와 놀랍도록 비슷합니다. -_-;

ArrayList도 내부적으로 크기 초과시에 .grow() 메소드를 호출 합니다.

private void grow(int minCapacity)

일정 개수 이상(2^31-8) 크기를 초과하면 OutOfMemoryError 오류가 나는 것도 벡터와 유사합니다.

Processing Image

벡터의 동작과 유사하기 때문에 여기서는 remove 할 때의 프로세스만을 자세하게 다뤄보겠습니다.

# 크기가 6인 ArrayList의 remove

1) 초기 상태
╋━╋━╋━╋━╋━╋━╋
┃ A┃ B┃ C┃ D┃ E┃ F┃
╋━╋━╋━╋━╋━╋━╋

2) 요소 C의 삭제
╋━╋━╋━╋━╋━╋━╋
┃ A┃ B┃ -┃ D┃ E┃ F┃
╋━╋━╋━╋━╋━╋━╋

3) 요소 C의 삭제 후 남은 빈 공간으로 차례대로 복사
           ◀
╋━╋━╋━╋━╋━╋━╋
┃ A┃ B┃ D┃ -┃ E┃ F┃
╋━╋━╋━╋━╋━╋━╋
               ◀
╋━╋━╋━╋━╋━╋━╋
┃ A┃ B┃ D┃ E┃ -┃ F┃
╋━╋━╋━╋━╋━╋━╋
                   ◀
╋━╋━╋━╋━╋━╋…╋
┃ A┃ B┃ D┃ E┃ F┃  ┃
╋━╋━╋━╋━╋━╋…╋

4) 최종
╋━╋━╋━╋━╋━╋………╋
┃ A┃ B┃ D┃ E┃ F┃(null)┃
╋━╋━╋━╋━╋━╋………╋

위의 이미지로 보셨듯이 벡터와 ArrayList의 삭제 동작은 위처럼 차례대로 기존 자리에 다음 요소를 복사하고 마지막에 null을 삽입합니다.

그런데 이런 동작을 매번 synchronized 키워드를 붙여서 처리하는 벡터라면 ArrayList보다도 성능적인 이슈가 매우 많이 생기겠죠?

Summary

ArrayList는 간단하고 빠르게 사용할 수 있는 Collection 클래스입니다. 가능하면 멀티 스레드가 아닌 이상 벡터가 아닌 ArrayList를 애용합시다. :D