22. 제네릭 컬렉션 활용 - Vector
Overview
제네릭 컬렉션의 Vector<E>에 대해서 알아본다.
Vector<E>
Vector<E>(이하 Vector 또는 벡터)는 List<E> 인터페이스를 구현한 클래스로서 가변 개수의 배열이 필요할 때 적합하다.
벡터에 삽입되는 요소의 수가 많아지면 자동으로 크기가 조절된다.
요소는 벡터의 맨 마지막이나 중간에 삽입될 수 있다.
이 경우 벡터는 삽입되는 요소의 뒤에 있는 모든 요소들을 한 자리씩 뒤로 이동시킨다.
요소를 삭제하면 뒤의 요소들을 앞으로 하나씩 이동시킨다.
다음 표는 Vector<E> 컬렉션의 주요 메소드를 보여준다.
메소드 | 설명 |
---|---|
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<E>의 E에 요소로 사용할 타입을 지정해야 한다.
예를 들어 정수 값만 삽입 가능한 벡터를 만들고자 하면 다음과 같이 E에 Integer를 지정하여 벡터를 생성한다.
Vector<Integer> v = new Vector<Integer>();
문자열만 다루는 벡터는 다음과 같이 생성할 수 있다.
Vector<String> stringVector; // 제네릭 컬렉션의 레퍼런스 변수 선언
stringVector = new Vector<String>(); // 문자열 벡터 선언
만일 Vector<E>에서 E에 구체적인 타입을 지정하지 않고 Vector로만 사용하는 경우 컴파일러는 경고 메시지를 출력한다.
생성된 벡터의 용량을 굳이 알 필요는 없다. 공간이 필요하면 자신의 용량을 스스로 조절하기 때문이다.
만일 용량을 초기에 설정하고자 한다면 다음과 같이 용량을 지정하는 생성자를 호출하면 된다.
Vector<Integer> v = new Vector<Integer>(5); // 초기 용량이 5인 벡터 생성
벡터에 요소 삽입
벡터에 요소를 삽입할 때 add()
를 사용한다. add()
는 요소를 벡터의 맨 뒤에 삽입한다.
현재 벡터 v
에 삽입할 수 있는 요소는 Integer 타입의 객체이므로 다음과 같이 하면 된다.
v.add(new Integer(5));
v.add(new Integer(4));
v.add(new Integer(-1));
위 코드는 정수 5, 4, -1을 순서대로 벡터 v
에 삽입한다.
그러나 JDK 1.5버전부터는 자동 박싱에 의해 다음과 같이 int 타입의 정수를 사용해도 자동으로 Integer 객체로 변환되어 삽입된다.
v.add(5); // 5 -> new Integer(5)로 변환되어 저장됨
v.add(4);
v.add(-1);
벡터 v
에 Integer 외의 다른 타입의 객체를 삽입할 수 없다.
다음 코드는 오류가 발생한다.
v.add("hello");
v.add(new Double(4.5));
v.add(new Person());
벡터에는 null
도 삽입할 수 있기 때문에 벡터를 검색할 때 null
이 있을 수 있음을 염두에 두어야 한다.
v.add(null);
벡터의 중간에 요소 객체를 삽입할 수 있다. 예를 들어, 인덱스 2의 위치에 정수 100을 삽입하는 코드는 다음과 같다.
v.add(2, 100); // v.add(2, new Integer(100));과 동일
벡터 내의 요소 알아내기
벡터 내에 존재하는 요소를 알아내기 위해서는 get()
, elementAt()
등의 메소드를 이용한다.
Vector<Integer> v = new Vector<Integer>();
v.add(5);
v.add(4);
v.add(-1);
벡터 v
의 get()
이나 elementAt()
메소드는 Integer
객체를 리턴한다.
벡터 v
에 삽입된 요소 중 인덱스 1의 위치에 있는 값을 읽어보자.
Integer obj = v.get(1); // 벡터의 1번째 요소를 얻어낸다.
int i = obj.intValue(); // obj에 있는 정수를 알아냄. 이 값은 4
위 두 문장을 다음 한 문장으로 쓸 수 있다.
int i = v.get(1); // 자동 언박싱
자동 언박싱에 의해 v.get(1)
이 리턴하는 Integer 객체의 정수 값이 int 타입의 변수 i
에 삽입된다.
벡터의 크기와 용량 알아내기
벡터의 크기와 용량은 서로 다른 의미이다.
벡터의 크기란 벡터에 들어 있는 요소의 개수를 말하며, 벡터의 용량이란 수용할 수 있는 크기를 말한다.
벡터의 크기를 알아내기 위해서는 다음과 같이 size()
메소드를 호출한다.
int len = v.size(); // 벡터의 크기. 벡터에 존재하는 요소 객체의 수
벡터의 용량은 다음 capacity()
메소드를 호출한다.
int cap = v.capacity(); // 벡터의 용량
벡터에서 요소 삭제
벡터 내에 임의의 인덱스에 있는 요소를 삭제할 수 있다.
v.remove(1); // 인덱스 1의 위치에 있는 요소 삭제
이 코드는 인덱스 1의 위치에 있는 요소를 삭제한다.
코드의 실행 결과 뒤에 있는 요소들이 한 자리씩 앞으로 이동한다.
다음과 같이 객체 레퍼런스를 이용하여 remove()
를 호출할 수도 있다.
Integer m = new Integer(100);
v.add(m);
...
v.remove(m);
벡터에 있는 모든 요소를 삭제하고자 한다면 다음과 같이 removeAllElements()
메소드를 호출한다.
v.removeAllElements();
컬렉션과 자동 박싱 / 언박싱
컬렉션은 객체들만 요소(element)로 다루기 때문에 기본 타입의 값은 Wrapper
클래스로 객체화하여 삽입한다.
다음은 정수를 Integer 객체로 만들어 저장하는 사례이다.
Vector<Integer> v = new Vector<Integer>();
v.add(new Integer(4));
v.add(new Integer(-1));
그러나 자동 박싱(auto boxing) 기능에 의해 int 타입을 값을 사용하면 자동으로 Integer 객체로 변환되어 삽입된다.
자동 박싱을 이용하여 위 코드를 수정하면 다음과 같다.
v.add(4); // 정수 4가 Integer(4)로 자동 박싱됨
v.add(-1); // 정수 -1이 Integer(-1)로 자동 박싱됨
컬렉션으로부터 값을 얻어내는 과정에서는 자동 언박싱(auto unboxing)이 일어난다.
다음 코드는 자동 언박싱을 활용하여 벡터로부터 정수값을 바로 얻어내는 코드이다.
int k = v.get(0); // k = 4
자동 박싱/언박싱은 모든 컬렉션 클래스에서 작동한다.
정수 값만 다루는 제네릭 Vector 생성 및 활용
public class VectorEx {
public static void main(String[] args) {
Vector<Integer> v = new Vector<Integer>();
v.add(5);
v.add(4);
v.add(-1);
// 벡터 중간에 삽입하기
v.add(2, 100); // 4, -1 사이에 정수 100 삽입
System.out.println("벡터 내의 요소 객체 수 : " + v.size());
System.out.println("벡터 내의 현재 용량 : " + v.capacity());
System.out.println("벡터 요소 출력");
for (int i = 0; i < v.size(); i++) {
int n = v.get(i);
System.out.println(n + " ");
}
System.out.print("벡터 모든 요소의 합 : ");
int sum = 0;
for (int i = 0; i < v.size(); i++) {
sum += v.elementAt(i);
}
System.out.println(sum + " ");
}
}
실행 결과
벡터 내의 요소 객체 수 : 4
벡터 내의 현재 용량 : 10
벡터 요소 출력
5
4
100
-1
벡터 모든 요소의 합 : 108
Point 클래스의 객체들만 저장하는 벡터 만들기
class Point3 {
private int x, y;
public Point3(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "(" + x + ", " + y + ")";
}
}
public class PointVectorEx {
public static void main(String[] args) {
Vector<Point3> v = new Vector<Point3>();
// Point 객체를 요소로만 가지는 벡터 생성
// 3개의 Point3 객체 삽입
v.add(new Point3(2, 3));
v.add(new Point3(-5, 20));
v.add(new Point3(30, -8));
System.out.println("Point");
for (int i = 0; i < v.size(); i++) {
Point3 p = v.get(i);
// 벡터에서 i번째 Point 객체 얻어내기
System.out.println(p);
// p.toString()을 이용하여 객체 p 출력
}
}
}
실행 결과
Point
(2, 3)
(-5, 20)
(30, -8)