본문 바로가기
Old Posts/Java

[Java] Vector 사용법 및 예제

by A6K 2021. 5. 29.

Vector

Vector 클래스는 ArraList 클래스처럼 List 인터페이스를 구현하고 있다. Vector 클래스는 ArrayList와 동일한 방법으로 데이터를 저장하고 있다. ArrayList처럼 저장 순서를 기억하고, 중복 데이터의 저장을 허용한다. 인덱스를 통해 특정 위치에 데이터를 추가하거나 특정 위치의 데이터를 제거할 수도 있다. Vector 객체 역시 데이터가 추가되면서 필요한 경우 자동으로 크기가 늘어나도록 구현되어 있다.(참고 : [Java] ArrayList 사용법 및 예제)

ArrayList 클래스와 Vector 클래스는 큰 차이가 없다고 생각해도 된다. 다만 Vector 클래스는 멀티스레드 환경에서 동기화처리가 되어 있다. 반면 ArrayList 클래스는 멀티스레드 환경에 대한 고려가 없다. 따라서 여러 스레드가 공유하는 데이터를 다룰 때에는 Vector 클래스를 사용하는게 좋다. 하나의 스레드에서만 사용되는 클래스의 경우 동기화처리가 필요없으므로 ArrayList 클래스를 사용하는 것이 성능상 이득을 불러온다.

Vector 사용법

Vector 생성

import java.util.Vector;

ArrayList와 마찬가지로 java.util.Vector 클래스를 통해 Vector가 제공된다. Vector를 사용할 클래스에 java.util.Vector 클래스를 import 해준다.

Vector vector = new Vector(); // Object 타입으로 선언
Vector<String> vector1 = new Vector<String>(); // 문자열 타입에 대한 Vector 선언
Vector<String> vector2 = new Vector<String>(10); // 초기 용량 설정
Vector<String> vector3 = new Vector<String>(otherCollection); // 다른 컬렉션 객체로부터 생성

ArrayList와 마찬가지로 Vector를 선언할 때 어떤 타입의 데이터를 다룰 것인지 '지네릭스(Generics)'를 통해서 타입을 명시해줘야한다. 만약 Vector 선언시 지네릭스로 타입을 명시하지 않으면 Object 타입이 기본으로 지정된다. 만약 int 같은 기본형(Primitive Type) 데이터를 다룰 예정이라면 Integer 같은 래퍼 클래스(Wrapper Class)를 사용해야한다. (참고 : [Java] 오토박싱(Auto Boxing)과 래퍼 클래스(Wrapper Class))

Vector 역시 데이터가 추가되면서 자동으로 용량이 늘어난다. 용량이 늘어나면서 새로운 배열을 생성하고 기존 값을 복사하는 동작을 수행하게 되는데, 미리 데이터의 개수를 알 수 있다면 초기에 용량을 설정해서 불필요한 데이터 복사를 줄여주는게 좋다.

마지막으로 다른 Collection 객체로부터 Vector를 초기화하는 생성자도 제공한다. Vector를 인자로 받는 API를 사용하기 위해서 Collection 타입 변환이 필요할 때 많이 사용된다.

Vector 값 추가

Vector 클래스에는 값을 추가하기 위한 add() 메소드가 있다.

Vector<String> vector = new Vector<String>();
vector.add("Data"); // 데이터 추가
vector.add(3, "Data3"); // 0번 위치에 데이터 추가

add() 메소드에 추가할 데이터를 인자로 주면 가장 마지막 부분에 데이터를 추가한다.

이 과정에서 새로 추가될 데이터를 위한 추가 공간이 없다면 더 큰 사이즈의 새로운 배열을 생성하고 기존 데이터들을 복사하는 동작이 수행된다. 사용자는 add() 메소드만 호출하면 되고, 내부 공간에 대한 고려는 하지 않아도 된다. (하지만 기존 데이터들을 복사하는 과정에서 오버헤드가 발생하고 성능 저하가 있을 수도 있다.)

add() 메소드에는 데이터 추가 위치를 명시할 수 있도록 숫자를 받는 경우도 있다.

Vector의 내부에 있는 배열 중간 부분에 데이터를 추가하게 될 경우, 요청한 위치에 새로운 데이터를 끼워 넣고, 그 뒤에 있는 데이터는 모두 한칸씩 뒤로 밀려나게 된다. 한칸씩 데이터들을 뒤로 밀어내는 동작은 Vector의 사이즈가 커질 수록 비효율적이 된다.

Vector 값 삭제

반대로 remove() 메소드와 clear() 메소드를 이용해서 Vector에 저장되어 있는 데이터들을 지울 수 있다.

vector.remove(1); // 1번째 값을 삭제
vector.clear(); // Vector 전체를 비우기

Vector에서 데이터를 지우는 remove() 메소드는 인덱스 값을 인자로 받는다.

remove(1) 메소드를 호출하면 1번 인덱스에 해당하는 데이터를 삭제한다. 데이터를 삭제하고 그 뒤에 있는 데이터들을 한칸씩 앞으로 땡겨주게 된다. add() 메소드와 마찬가지로 Vector 크기가 커질 수록 이 동작이 오래 걸린다.

Vector 객체를 초기화하려면 clear() 메소드를 사용하면 된다. 내부 배열의 값을 모두 null로 닦아 준다.

Vector 값 확인

Vector에 저장되어 있는 데이터를 확인하려면 get() 메소드를 이용하면 된다.

vector.get(0); // 0번 인덱스에 해당하는 값을 확인

Vector 전체 값 순회

Vector에 들어있는 모든 값을 순회하기 위해 for문을 사용할 수 있다.

Vector<String> vector;

...

// for 문을 이용한 접근
for (String str : vector) {
  System.out.println(str);
}

혹은 Iterator를 이용해서 while 문으로 접근할 수 있다.

Iterator iterator = vector.iterator();
while (iter.hasNext()) {
  String str = iter.next();
  System.out.println(str);
}

Vector 값 검색

특정 값이 Vector에 있는지 확인하거나 있다면 몇 번째 인덱스에 있는지 확인하는 메소드도 존재한다.

Vector<String> vector = new Vector<String>(Arrays.asList("Data1", "Data2", "Data3"));

boolea isContained = vector.contains("Data1"); // true 리턴
int index = vector.indexOf("Data2"); // 1 반환.. 만약 값이 없으면 -1 리턴

contains() 메소드는 equals() 메소드를 이용해서 특정 객체가 Vector에 있는지 확인한다. 있으면 true를 리턴하고, 없으면 false를 리턴한다.

indexOf() 메소드는 마찬가지로 특정 값에 해당하는 객체가 Vector에 있는지 확인한다. 다만 true/false가 아닌 몇 번째 인덱스에 해당하는 값인지 숫자를 리턴한다. 만약 ArrayList에 값이 없다면 -1이 리턴된다.

댓글