● ArrayList
ArrayList는 컬렉션 프레임워크에서 가장 많이 사용되는 컬렉션 클래스이다. 인터페이스 List를 상속받으므로 그 특징 또한 그대로 물려받는다.
ArrayList는 Array와 비슷한 면이 많지만 같진않다. 왜냐하면, Array는 정적 배열이고 ArrayList는 대표적인 동적 배열이다. ArrayList는 정적배열과는 다르게 추가, 삭제등을 할 수 있다. 이번 포스팅에선 ArrayList가 데이터를 저장하고 삭제, 추가하는 과정을 코드를 통해 조금 더 상세히 알아볼 것이다.
1) 순차적 데이터 저장 및 추가
ArrayList는 순차적으로 데이터를 저장하고 그 저장한 순서가 유지된다.
데이터를 추가할때는 ArrayList의 메서드, boolean add (Object o) 객체를 사용한다.( ArrayList 마지막에 추가, 추가 성공 시 true 반환)
public class ArrayList {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
System.out.println(list1);
}
}
실행결과
[5, 4, 2, 0, 1, 3]
만약 중간에 추가하고 싶다면, 메서드 boolean add ( index , Object o)를 사용한다.(원하는 위치(index)에 Object를 저장)
public class ArrayListEx01 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
list1.add(3,9); //Integer는 써도 안써도 그만
System.out.println(list1);
}
}
실행결과
[5, 4, 2, 9, 0, 1, 3]
3번 인덱스에 9가 추가된 것을 확인할 수 있다.
2) ArrayList 데이터의 삭제
데이터의 삭제는 remove(index) 를 사용한다. (해당 index에 저장된 데이터를 삭제)
public class ArrayList {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
for (int i = list1.size() - 1; i >= 0; i--) {
list1.remove(i); System.out.println(list1);
}
}
}
실행결과
[5, 4, 2, 0, 1]
[5, 4, 2, 0]
[5, 4, 2]
[5, 4]
[5]
[]
배열의 마지막 요소였던 3부터 순차적으로 전부 지운다.
갑자기 문득 궁금한 점이 생긴다. 넣을 땐 5부터 넣었는데 왜 삭제할 땐 마지막에 넣은 3부터(요소의 마지막부터) 지우는 것일까?
반대로 첫번째 요소, 5부터 지워보자
public class ArrayListEx01 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
long start = System.currentTimeMillis();
for (int i = 0; i <= list1.size() - 1; i++) {
list1.remove(i); System.out.println(list1);
}
long end = System.currentTimeMillis();
System.out.println(end-start);//소요시간
}
}
실행결과
[4, 2, 0, 1, 3]
[4, 0, 1, 3]
[4, 0, 3]
뒷요소부터 지울땐 정상적으로 지워졌지만 처음부터 지우려하니 요소가 다 지워지지도 않았고 지워지는 순서도 엉망인 것을 볼 수 있다.
그 이유는 , 배열의 맨 앞이나 중간의 요소를 지울 때, 배열의 빈부분을 채워주어야 하는데 이 과정에서 배열의 복사가 일어난다. 배열을 복사하여 붙여 넣음으로써 삭제된 요소들을 앞으로 한 칸씩 당기기 때문이다.
처음에 5를 지우고 그다음에 4를 지워야 하는데 배열의 복사가 일어나 5의 빈자리를 메꾸어주었기 때문에 4가 있어야 할 1번 인덱스에 2가 오게 되면서 4는 지우지 못하고 2를 지워버리며 결과적으론 지우지 못하는 요소들이 남게 돼버린다.
ArrayList의 이러한 특성 때문에 맨 뒷부분부터 요소를 제거해나가면 이러한 과정(배열의 복사)이 필요가 없으므로 ArrayList는 마지막 요소부터 제거해주는 것이 효율적이다.
3) 메서드 remove()
remove메서드를 사용할 때 배열의 복사가 어떻게 일어나는지 코드를 보면서 이해를 해보자
Object[] data = null;
//생성자에서 size를 받아서 저장
@Override
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; //마지막 index를 비워줌
size--;
return oldObj;
}
위의 메서드를 이용하여 배열의 중간에 있는 요소를 지워보자
public class ArrayList {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(5); //용량을 5로 수정
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(2));
list1.add(new Integer(3));
list1.add(new Integer(4));
list1.remove(2);
System.out.println(list1);
}
}
위의 코드는 ArrayList객체를 생성하면서 용량을 5로 선언하였다는 것을 참고하자.
실행결과
[0, 1, 3, 4]
2를 지우는 과정에서 배열의 복사가 일어났다. 이를 그림으로 표현해보자면 아래와 같다.
이렇듯, 배열의 복사 과정은 복잡하고 시간이 더 걸리므로 가능하면 배열의 복사가 일어나지 않게 하기 위하며 인덱스의 마지막(index = size-1)부터 지워나가면 아래 그림과 같은 복잡한 과정을 거치지 않고 온전하게 데이터의 삭제가 가능해진다.
'Java > Java Study' 카테고리의 다른 글
[Collections Framework] LinkedList (vs Array) (0) | 2021.05.31 |
---|---|
[Collections Framework] Iterator 와 메서드 iterator (0) | 2021.05.27 |
[Collections Framework] 컬렉션 프레임워크란? (0) | 2021.05.24 |
[객체지향] 인터페이스(Interface) (5/24 어휘수정) (0) | 2021.05.16 |
[객체지향] 추상 클래스 (5월18일 추가내용) (0) | 2021.05.16 |