...
Vector 컬렉션
Vector은 ArrayList와 같이 List 인터페이스를 상속받는 컬렉션 프레임워크이며, 사용법은 ArrayList와 크게 다르지 않다.
컬렉션 프레임워크가 나오기전에 가변 개수의 배열이 필요할 때 과거에 사용되었으며, 현대에는 성능 상 사용하지않고 ArrayList를 사용한다. 다만 호환성을 위해서 제거하지않고 남겨두었다고 보면 된다. 오래된 클래스를 굳이 배울 필요가 있나 싶겠지만, 멀티 쓰레드 환경에서의 Vector 컬렉션의 동기화에 대해 짚고 넘어갈 필요가 있기 때문이다.
Vector 사용법
Vecotor 컬렉션의 메서드 구성은 ArrayList와 거의 같다고 보면 된다.
메 서 드 | 설 명 |
boolean add(E element) | 벡터의 맨 뒤에 element 추가 |
void add(int index, E element) | 인덱스 index에 element를 삽입 |
int capacity() | 벡터의 현재 용량 리턴 |
boolean addAll(Collection<? extends E> c) | 컬렉션 c의 모든 요소를 벡터의 맨 뒤에 추가 |
void clear() | 벡터의 모든 요소 삭제 |
boolean contains(Object o) | 벡터가 지정된 객체 o를 포함하고 있으면 true 리턴 |
E elementAt(int index) | 인덱스 index의 요소 리턴 |
E get(int index) | 인텍스 index의 요소 리턴 |
int indexOf(Object 0) | o와 같은 첫 번째 요소의 인덱스 리턴. 없으면 -1 리턴 |
boolean isEmpty() | 벡터가 비어 있으면 true 리턴 |
E remove(int index) | 인덱스 index의 요소 삭제 |
boolean remove(Object o) | 객체 o와 같은 첫 번째 요소를 벡터에서 삭제 |
void removeAllElements() | 벡터의 모든 요소를 삭제하고 크기를 0으로 만듦 |
int size() | 벡터가 포함하는 요소의 개수 리턴 |
Object[] toArray() | 벡터의 모든 요소를 포함하는 배열 리턴 |
Vector 생성
Vector 컬렉션의 구조는 ArrayList나 LinkedList와 별반 다르지 않다.
// 타입설정 int타입만 사용가능
Vector<Integer> num = new Vector<>();
// 초기 용량(capacity) 지정
Vector<String> v2 = new Vector<>(10);
// 초기값 지정
Vector<Integer> v3 = new Vector<>(Arrays.asList(1,2,3));
Vector 요소 추가 & 삽입
Vector<Integer> v = new Vector<Integer>();
// 값 추가
v.add(5);
v.add(4);
v.add(-1);
// 인덱스 2 위치에 값 4 삽입 (삽입하기 위해 옆의 요소들은 뒤로 이동)
v.add(2, 4);
Vector 요소 삭제
Vector<Integer> v = new Vector<Integer>();
v.add(5);
v.add(100);
v.add(-1);
v.remove(1); // 100 제거
System.out.println(v); // [5, -1]
여기서 ArrayList와 다른 메서드가 보이는데 removeAllElements() 는 clear() 메서드와 달이 모든 요소를 지우고 용량(capacity)도 0으로 만든다.
// 모든 값 제거
v.clear(); // 요소만 제거
v.removeAllElements(); // 요소도 제거하고 용량도 0으로 만듬
Vector 용량 & 크기 구하기
또한 capacity() 메서드를 통해 컬렉션의 용량을 반환받을 수 있다. (ArrayList에서는 불가능)
// Vector 초기 용량 10으로 생성
Vector<Integer> v = new Vector<>(10);
// 값 추가
v.add(1);
v.add(2);
// Vector 자료 총 개수(size)
System.out.println(v.size()); // 2
// Vector 용량
System.out.println(v.capacity()); // 10
Vector 요소 출력
Vector에서 값을 출력하는 방법도 역시 ArrayList와 동일하다.
마찬가지로 Collection 인터페이스를 상속하기 때문에 Iterator도 사용이 가능하다.
Vector<Integer> list = new Vector<Integer>(Arrays.asList(1,2,3));
// 0번째 index 출력
System.out.println(list.get(0));
// for문을 통한 전체 요소 출력
for(Integer i : list) {
System.out.println(i);
}
// Iterator를 통한 전체 요소 출력
Iterator iter = list.iterator();
while(iter.hasNext()){
System.out.println(iter.next()); // 값 출력
}
Vector의 동기화
Vector는 ArrayList와 기능 상 거의 동일하다. 메서드 구성도 거의 같다. 하지만 한 가지 다른 점이 있는데 바로 메서드에 synchronized 키워드 유무이다. 실제로 Vector 클래스 정의 소스 파일에 가서 메서드들을 보면 synchronized 키워드가 걸려있음을 볼 수 있다.
synchronized 키워드는 멀티 쓰레드 환경에서 두개 이상의 쓰레드가 하나의 변수에 동시에 접근을 할 때 Race condition(경쟁상태)이 발생하지 않도록 한다. 한마디로 쓰레드가 해당 메서드를 실행하는 동안 다른 쓰레드가 접근하지 못하도록 메서드를 잠금(lock)을 거는 것이다.
아래 그림 처럼 thread-1이 메서드에 진입하는 순간 나머지 thread-2 ~ 4의 접근을 제한하고, thread-1이 완료가 되면 다음 스레드를 접근시키는 형식이다. 그래서 Vector 클래스는 멀티 쓰레드 환경에서 안전하게 사용할 수 있는 컬렉션이라고 한다.
하지만 Vector는 완벽한 동기화가 아니다. 그리고 몇가지 치명적인 문제점이 존재한다. 이에 대해서 다음 ArrayList와 Vector을 비교한 포스팅을 참고하여 어느 컬렉션을 써야하는지에 대해 알아보자.
# 참고자료
https://www.programiz.com/java-programming/library/arraylist/sublist
https://www.booksr.co.kr/html/book/book.asp?seq=697057
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.