Dico

[Java] Class Vector

Collection Framework

데이터 군을 저장하는 클래스들을 표준화한 설계

컬렉션 Collection :  다수의 데이터. 데이터 그룹

프레임웍 Framework :  표준화된 프로그래밍 방식.

Class Vector

  • 객체에 대한 참조값을 저장하는 배열 

     서로 다른 타입을 가지는 참조형 데이터를 저장. 기본형 데이터는 Wrapper로 변형 후 저장 가능.

  • List 인터페이스를 구현

     저장된 순서를 유지한다.

  • Object 배열을 이용하여 데이터를 순차적으로 저장 

     용량 변경 비효율적. 읽기, 저장하기 효율적.

  • 처음 인스턴스 생성 시, 저장할 데이터의 개수를 잘 고려하여 충분한 용량의 인스턴스를 생성한다.

     자동적으로 크기가 늘어나긴 하지만 그 과정에서 처리시간이 많이 소요된다.

ArrayList와 Vector

배열을 이용한 자료구조는 데이터를 읽어오고 저장할 때 효율이 좋다.

용량을 변경해야 할 때, 새로운 배열을 생성한 후 기존의 배열로부터 새로 생성된 배열로 데이터를 복사해야 하는 단점이 있다.

import java.util.Vector;

public class Test {
    public static void main(String[] args) {
        Vector<String> v = new Vector<>(5);
        v.add("1");
        v.add("2");
        v.add("3");
        print(v);                      // size : 3 / capacity : 5

        v.trimToSize();
        print(v);                      // size : 3 / capacity : 3

        v.ensureCapacity(6);
        print(v);                      // size : 3 / capacity : 6

        v.setSize(7);
        print(v);                      // size : 7 / capacity : 12

        v.clear();
        print(v);                      // size : 0 / capacity : 12
    }

    public static void print(Vector v) {
        System.out.println("size : " + v.size() + " / capacity : " + v.capacity());
    }
}
  • 용량(capacity)이 5인 Vector v에 객체 3개 저장
0x1000x9000x8000x700nullnull
v0x9000x8000x700
0x100123
  • v.trimToSize()

    빈 공간 제거

    배열의 크기를 변경할 수 없기 때문에 새로운 배열을 생성해서 그 주소값을 변수 v에 할당한다.

    기존 Vector 인스턴스는 제거된다.

0x2000x9000x8000x700
v0x9000x8000x700
0x200123
  • v.ensureCapacity(6)

    capacity가 최소한 6이 되도록 한다.

    만일 크기가 6이상이라면 아무 일도 일어나지 않는다.

0x3000x9000x8000x700nullnullnull
v0x9000x8000x700
0x300123
  • v.setSize(7)

    capacity가 충분하지 않을 경우 자동적으로 기존의 크기보다 2배의 크기로 증가한다.

0x4000x9000x8000x700nullnullnullnullnullnullnullnullnull
v0x9000x8000x700
0x400123
  • v.clear()

    v의 모든 요소를 삭제한다.

0x400nullnullnullnullnullnullnullnullnullnullnullnull
v
0x400

Vector

다음 예제는 Vector 클래스의 실제 코드를 바탕으로 이해하기 쉽게 재구성한 것이다.

package blog;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class MyVector implements List {
    Object[] date = null;
    int capacity = 0;
    int size = 0;

    MyVector(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("유효하지 않은 값입니다. :" + capacity);
        }

        this.capacity = capacity;
        date = new Object[capacity];
    }

    MyVector() {
        this(10);
    }

    // 최소한의 저장 공간 확보
    public void ensureCapacity(int minCapacity) {
        if (minCapacity - date.length > 0) {
            setCapacity(minCapacity);
        }
    }

    public boolean add(Object obj) {
        ensureCapacity(size + 1); // 새 객체 저장하기 전에 공간 확보
        date[size++] = obj;
        return true;
    }

    public Object get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("범위를 벗어났습니다.");
        }
        return date[index];
    }

    public Object remove(int index) {
        Object oldObj = null;

        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("범위를 벗어났습니다.");
        }
        oldObj = date[index];

        // 삭제하려는 객체가 마지막 객체가 아니라면, 배열 복사를 통해 빈자리를 채워야 한다.
        if (index != size - 1) {
            System.arraycopy(date, index + 1, date, index, size - index - 1);
        }

        // 마지막 데이터를 null. 마지막 요소의 index = size-1
        date[size - 1] = null;
        size--;
        return oldObj;
    }

    public boolean remove(Object obj) {
        for (int i = 0; i < size; i++) {
            if (obj.equals(date[i])) {
                remove(i);
                return true;
            }
        }
        return false;
    }

    public void trimToSize() {
        setCapacity(size);
    }

    public void setCapacity(int capacity) {
        if (this.capacity == capacity)
            return; // 크기가 같으면 변경 취소

        Object[] temp = new Object[capacity];
        System.arraycopy(date, 0, temp, 0, size);
        date = temp;
        this.capacity = capacity;
    }

    public void clear() {
        for (int i = 0; i < size; i++) {
            date[i] = null;
        }
        size = 0;
    }

    public Object[] toArray() {
        Object[] result = new Object[size];
        System.arraycopy(date, 0, result, 0, size);

        return result;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public int capacity() {
        return capacity;
    }

    public int size() {
        return size;
    }

    /* interface List로부터 상속받은 method들 */

    @Override
    public void add(int arg0, Object arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean addAll(Collection arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean addAll(int arg0, Collection arg1) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean contains(Object arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean containsAll(Collection arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public int indexOf(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Iterator iterator() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int lastIndexOf(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public ListIterator listIterator() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public ListIterator listIterator(int index) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean removeAll(Collection c) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean retainAll(Collection c) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Object set(int index, Object element) {
        // TODO Auto-generated method stub
        return null;
    }
    
    @Override
    public List subList(int fromIndex, int toIndex) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object[] toArray(Object[] a) {
        // TODO Auto-generated method stub
        return null;
    }
}
  • Object remove(int index)

 1. 삭제할 객체의 바로 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 객체를 덮어쓰는 방식으로 처리한다.

 2. 마지막 데이터는 null로 변경한다.

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

index기존덮기변경감소
01111
12333
23444
244null(null)
4(null)(null)(null)(null)
5(null)(null)(null)(null)

    배열에 객체를 순차적으로 저장할 때, 객체를 마지막에 지정된 것부터 삭제할 때

    System.arraycopy()를 호출하지 않으므로 작업시간이 짧다.

    배열의 중간에 위치한 객체를 추가하거나, 삭제할 때는 System.arraycopy()를 호출해서

    다른 데이터의 위치를 이동시켜 줘야 하기 때문에 다루는 데이터의 개수가 많을 수록 작업시간이 오래 걸린다.

Vector API

참고 서적: 자바의 정석 3판 2