본문 바로가기

프로그래밍/Java

Collection framework에 대해(2)

Vector와 ArrayList


- ArrayList는 기존의 Vector를 개선한 것으로 구현원리와 기능적으로 동일하다고 할 수 있다.

- Vector는 Collection framework가 도입되기 이전부터 존재하던 구버전이며, ArrayList는 framework가 도입된 후 생긴 클래스이다.

- Vector는 자체적으로 동기화(멀티 스레드)처리가 되어 있으나 ArrayList는 그렇지 않다는 큰 차이가 있다. 하지만 싱글 스레드의 프로그램을 만들려고 할 때는 ArrayList가 더 효율적이라 할 수 있다.

- Vector와 ArrayList 모두 List인터페이스를 구현하기 때문에 저장순서가 유지되며 중복을 허용하고 있다. 또한 데이터의 저장 공간으로 배열을 사용하는 배열 기반 클래스이다.

- ArrayList를 생성할 때 배열의 크기를 설정하지 않는다면 자동으로 크기 10의 배열이 생성되게 된다.

- 객체 요소를 add할 때 int형 등은 new Integer의 형식으로 박싱을 해주어야 했지만 JDK1.5버전 이후부터 오토 박싱을 지원하며 사용자는 박싱에 대해 신경쓰지 않고 컴파일러가 오토박싱을 수행하게 되었다.

- 이미 객체가 저장되어 있던 인덱스에 새로운 객체를 add하게 되면 기존에 있던 객체 요소는 한 인덱스씩 뒤로 밀려나게 된다.


ArrayList에 저장된 객체의 삭제 과정

- [0, 1, 2, 3, 4, null, null]의 ArrayList에 저장된 세 번재 데이터(data[2])를 삭제하는 과정으로 list.remove(2);를 호출한 상황이다.

1. 삭제할 데이터 아래의 데이터들을 한 칸씩 위로 복사해서 삭제할 데이터를 덮어쓴다.

System.arraycopy(data, 3, data, 2, 2);

//data[3]에서 data[2]로 2개의 데이터를 복사하라는 의미이다.

2. 데이터가 모두 한 칸씩 이동했으므로 마지막 데이터를 null로 변경한다.

data[size - 1] = null; 

3. 데이터가 삭제되어 데이터의 개수라 줄었으므로 size의 값을 감소시킨다.

size--;

- 보통 2와 3은 한 번에 표현하게 된다.

data[--size] = null;

- 중간의 데이터가 아닌 마지막 데이터를 삭제하게 될 경우 배열을 복사하는 과정인 1번 과정은 필요가 없어지고 2, 3번 과정만 수행하면 데이터가 삭제된다.


- ArrayList에 저장된 첫 번째 객체부터 삭제하는 경우(배열 복사 발생)

정상적으로 remove가 수행되나 for문의 인덱스값은 계속 증가함에 반해 ArrayList의 값은 한 칸씩 줄어들며 삭제를 수행해 인덱스0에 1의 값이 저장되어 결과적으로 한 칸씩 띄어 데이터가 남게 되는 결과가 발생한다.

- ArrayList에 저장된 마지막 객체부터 삭제하는 경우(배열 복사 발생하지 않음)

배열에 저장된 객체들이 자리이동을 하지 않은 상태에서 데이터를 삭제하게 되어 배열이 복사되어 찌꺼기가 남지 않고 깔끔하게 remove명령이 완료된다.


Vector의 크기(size)와 용량(capacity)

- 여기서 크기는 저장된 객체의 개수를 의미하며, 용량은 배열의 길이를 의미한다.

- Vector v = new Vector(5);를 이용해 용량이 5인 벡터를 생성하고 v.add("1");...을 3번 하여 크기를 3으로 만들어준다.

- v.trimToSize();메소드가 호출되게 되면 Vector의 용량을 크기와 같게 만들어준다. 5였던 용량을 3으로 만들어준다는 것인데, 배열은 만들어진 후에 길이 변경이 불가능하여 용량이 3인 새로운 배열을 생성하여 기존 벡터에 있던 데이터들을 그대로 복사하여 옮기게 된다.

- v.ensureCapacity(6);메소드를 호출하게 되면 용량을 6으로 맞추게 되는데 만약 이미 벡터의 용량이 6 이상이면 변화가 없고, 6보다 작게 되면 크기가 6인 새로운 배열을 생성하고 기존 배열에 있던 데이터들을 복사하여 옮기게 된다.

- v,setSize(7);메소드를 호출하게 되면 벡터의 크기를 7로 맞추게 되는데 이전 벡터의 용량이 6이였으므로 크기 7에 필요한 용량을 맞출 수가 없어 자동적으로 용량을 6의 두배인 12로 변경하게 된다. 만일 용량이 부족할 때 증가시켜줄 크기를 지정해주는 지정자를 설정해놓았다면 두배씩 증가하지 않고 해당 증가량만큼만 증가시키게 된다.

- v.clear()메소드를 이용하게 되면 Vector에 저장되어 있던 모든 요소들을 제거하게 된다.


Vector 구현하기

- 객체를 저장할 객체 배열(objVector)와 크기(size)를 저장할 변수를 선언한다.

- 생성장 MyVector(int capacity)와 기본 생성자 MyVector()를 선언한다.

- 메소드 구현

1. int size()

컬렉션의 크기를 반환한다.

2. int capacity()

컬렉션의 용량을 반환한다.

3. boolean isEmpty()

컬렉션이 비어있는지 확인한다.

4. void clear()

컬렉션의 객체를 모두 제거한다(객체배열의 모든 요소를  null로 바꾼다.)

5. Object get(int index)

컬렉션에서 지정된 index에 저장된 객체를 반환한다.

6. int indexOf(Object obj)

지정된 객체의 index를 반환한다. 찾지 못한다면 -1을 반환한다.

int indexOf(Object obj) {

//순차 검색의 방식으로 해당 인덱스를 찾게 된다.

for (int i = 0; i < size; i++)

if (objVector[i].equals(obj))

return i;

return -1;

}

7. void setCapacity(int capacity)

컬렉션의 용량을 변경한다.(기본적인 Vector의 메소드는 아니다)

void setCapacity(int capacity) {

Object[] tmp = new Object[capacity];

//그냥 size개수만큼 복사하게 될 경우 size보다 capacity가 더 작을 때 오류가 발생하게 된다. 하여 Math.min을 이용하여 둘 중 더 작을 수에 맞춰 복사를 수행하도록 만들어준다.

System.arraycopy(objVector, 0, tmp, 0, Math.min(size, capacity));

objVector = tmp;

}

8. void ensureCapacity(int minCapacity)

컬렉션의 용량을 확보한다.

void ensureCapacity(int minCapacity) {

if (minCapacity > objVector.length)

setCapacity(minCapacity);

}

9. Object remove(int index)

컬렉션에서 객체를 삭제한다.

Object remove(int index) {

if (index < 0 || index >= size)

return throw new IndexOutOfBoundsException("범위를 벗어났습니다.");

Object oldObj = objVector[index];

if (index != size - 1)

//삭제할 인덱스 다음 인덱스부터 복사해 삭제할 인덱스를 덮는 명령을 준다.

System.arraycopy(objVector, index + 1, objVector, index, size - 1 - index);

objVector[--size] = null;

return oldObj;

}

10. boolean add(Object obj)

컬렉션에 객체를 추가한다.

boolean add(Object obj) {

ensureCapacity(size++);

objVector[size] = obj;

size++;

return true;

}

'프로그래밍 > Java' 카테고리의 다른 글

Iterator와 Enumeration, ListIterator에 대해  (0) 2019.04.25
Stack과 Queue에 대해  (0) 2019.04.22
Collection framework에 대해 (3)  (0) 2019.04.21
Collections framework에 대해 (1)  (0) 2019.04.19
Hashset에 대해  (0) 2019.04.18