아마도 당신은 이미 Java에서 배열을 보았고 주요 단점 중 하나가 크기 불변성이라는 것을 알고 있을 것입니다. 특정 크기의 배열을 만든 후에는 나중에 변경할 수 없습니다. 이 문제를 해결하는 Java 언어의 여러 Java Collection 프레임워크 클래스가 있습니다. 그 중 하나가 자바 벡터 클래스입니다. 이 기사에서 논의 될 것입니다.

벡터 클래스란?

서문에서 썼듯이 Java Collection Framework의 Vector 클래스는 배열의 정적 크기 문제를 제거합니다. Java Vector는 일종의 동적 배열이며 크기가 커지거나 줄어들 수 있습니다. Vector 컬렉션 클래스를 사용하여 요소 그룹을 간단한 개체로 저장하고 다양한 메서드를 통해 조작할 수 있습니다. Vector 클래스는 java.util 패키지에서 사용할 수 있습니다. 따라서 사전에 배열의 크기를 모르거나 프로그램 수명 동안 크기를 변경할 수 있는 "배열"이 필요한 경우 Java의 벡터를 사용할 수 있습니다. Vector클래스는 이미 꽤 오래되었으며 대부분의 경우 이를 대체할 수 있는 나중에 컬렉션이 나타났습니다. Java Vector의 유명한 "아날로그"는 ArrayList 클래스입니다. 이러한 클래스 간의 가장 중요한 차이점은 Vector가 동기화되는 반면 ArrayList는 동기화되지 않는다는 것입니다. 나중에 "Vector 클래스의 문제점" 섹션에서 이 두 클래스와 Vector 클래스 더 현대적인 아날로그 사이의 다른 차이점에 대해 이야기하겠습니다 .

자바 벡터 메서드

Java 벡터 메서드는 다음과 같습니다.
  • void add(int index, Object element) 벡터의 지정된 위치에 지정된 요소를 삽입합니다.

  • boolean add(Object o)는 지정된 요소를 벡터의 끝에 추가합니다.

  • boolean addAll(Collection c) 지정된 컬렉션의 모든 요소를 ​​지정된 컬렉션 반복자가 반환하는 순서대로 벡터의 끝에 추가합니다.

  • boolean addAll(int index, Collection c) 지정된 Collection 내의 모든 요소를 ​​지정된 위치의 벡터에 삽입합니다.

  • void addElement(Object obj)는 지정된 구성 요소를 이 벡터의 끝에 추가하여 크기를 1씩 늘립니다.

  • int capacity()는 이 벡터의 현재 용량을 반환합니다.

  • void clear()는 이 벡터에서 모든 요소를 ​​제거합니다.

  • 객체 clone()은 이 벡터의 복제본을 반환합니다.

  • boolean contains(Object elem) 지정된 객체가 이 벡터의 구성 요소인지 여부를 테스트합니다.

  • boolean containsAll(Collection c)는 벡터가 지정된 Collection의 모든 요소를 ​​포함하는 경우 true를 반환합니다.

  • void copyInto(Object[] anArray)는 이 벡터의 구성 요소를 지정된 배열에 복사합니다.

  • Object elementAt(int index)는 지정된 인덱스에 있는 구성 요소를 반환합니다.

  • Enumeration elements()는 이 벡터 구성 요소의 열거를 반환합니다.

  • void ensureCapacity(int minCapacity)는 필요한 경우 이 벡터의 용량을 늘려 최소 용량 인수로 지정된 구성 요소 수 이상을 보유할 수 있도록 합니다.

  • boolean equals(Object o)는 지정된 객체를 이 벡터와 비교합니다.

  • 객체 firstElement()는 이 벡터의 첫 번째 구성 요소(인덱스 0의 요소)를 반환합니다.

  • Object get(int index)는 이 벡터의 지정된 위치에 있는 요소를 반환합니다.

  • int hashCode()는 이 벡터의 해시 코드 값을 반환합니다.

  • int indexOf(Object elem) equals 메서드를 사용하여 동등성을 테스트하면서 주어진 인수의 첫 번째 항목을 검색합니다.

  • int indexOf(Object elem, int index) index에서 시작하여 equals 메소드를 사용하여 동등성을 테스트하면서 주어진 인수의 첫 번째 항목을 검색합니다.

  • void insertElementAt(Object obj, int index) 지정된 인덱스에서 이 벡터에 구성요소로 지정된 객체를 삽입합니다.

  • 부울 isEmpty()는 누락된 구성요소에 대해 이 벡터를 테스트합니다.

  • 객체 lastElement()는 벡터의 마지막 구성 요소를 반환합니다.

  • int lastIndexOf(객체 요소)는 이 벡터에서 지정된 객체가 마지막으로 나타나는 인덱스를 반환합니다.

  • int lastIndexOf(Object elem, int index) 지정된 인덱스에서 시작하여 지정된 객체를 역방향으로 검색하고 해당 인덱스를 반환합니다.

  • Object remove(int index)는 이 벡터의 지정된 위치에 있는 요소를 제거합니다.

  • boolean remove(Object o)는 이 벡터에서 지정된 요소의 첫 번째 항목을 제거합니다. 벡터에 요소가 포함되어 있지 않으면 변경되지 않습니다.

  • boolean removeAll(Collection c)는 지정된 Collection에 포함된 벡터에서 모든 요소를 ​​제거합니다.

  • void removeAllElements()는 벡터에서 모든 구성 요소를 제거하고 크기를 0으로 설정합니다.

  • boolean removeElement(Object obj)는 이 벡터에서 인수의 첫 번째(가장 낮은 인덱스) 항목을 제거합니다.

  • void removeElementAt(int index) 인덱스에서 요소를 제거합니다.

  • protected void removeRange(int fromIndex, int toIndex) 인덱스가 fromIndex(포함)와 toIndex(포함) 사이에 있는 모든 요소를 ​​이 List에서 배타적으로 제거합니다.

  • boolean retainAll(Collection c)는 지정된 Collection에 포함된 벡터의 요소만 유지합니다.

  • Object set(int index, Object element)는 이 벡터의 지정된 위치에 있는 요소를 지정된 요소로 바꿉니다.

  • void setElementAt(Object obj, int index) 이 벡터의 지정된 인덱스에 있는 구성 요소를 지정된 객체로 설정합니다.

  • void setSize(int newSize) 이 벡터의 크기를 설정합니다.

  • int size()는 이 벡터의 구성 요소 수를 반환합니다.

  • List subList(int fromIndex, int toIndex)는 fromIndex(포함)와 toIndex(배타적) 사이에서 이 목록 부분의 표현(보기)을 반환합니다.

  • Object[] toArray()는 이 벡터의 모든 요소를 ​​올바른 순서로 포함하는 배열을 반환합니다.

  • Object[] toArray(Object[] a)는 이 벡터의 모든 요소를 ​​올바른 순서로 포함하는 배열을 반환합니다. 반환된 배열의 실행 유형은 지정된 배열의 유형입니다.

  • String toString()은 각 요소의 문자열 표현을 포함하는 이 벡터의 문자열 표현을 반환합니다.

  • void trimToSize()는 이 벡터의 용량을 벡터의 현재 크기로 자릅니다.

자바 벡터 예


import java.util.Vector;

public class VectorExample {

   public static void main(String[] args) {
       Vector vector = new Vector();
       System.out.println("the size of the empty vector = " +  vector.size());
       //adding some vector elements
       vector.add("Johnny");
       vector.add("Ivy");
       vector.add("Ricky");
       System.out.println(vector); 
       
       //adding more vector elements       
       vector.add("Johnny");
       vector.add("Paul");
       System.out.println(vector);
       System.out.println("the size of the vector = " +  vector.size());
       System.out.println("the first element of the vector = " + vector.firstElement());

       //here the program will print out the first appearance of "Johnny" element
       System.out.println(vector.indexOf("Johnny"));
       //program will print out the first appearance of "Johnny" element starting from the element 1
       System.out.println(vector.indexOf("Johnny", 1));
       vector.clear(); //deleting all vector elements
       System.out.println("the size of the vector after clear method = " +  vector.size());

   }
}
이 프로그램의 출력은 다음과 같습니다.
빈 벡터의 크기 = 0 [Johnny, Ivy, Ricky] [Johnny, Ivy, Ricky, Johnny, Paul] 벡터의 크기 = 5 벡터의 첫 번째 요소 = Johnny 0 3 지우기 후 벡터의 크기 방법 = 0

벡터 클래스에 어떤 문제가 있습니까?

Java Vector 클래스 의 문서에 따르면 프로그램에서 스레드 안전 구현이 필요하지 않은 경우 Vector (Collection Framework에 더 효과적인 참여자) 대신 ArrayList를 사용하는 것이 좋습니다. Vector 대신 ArrayList 클래스를 사용하여 위의 예제를 약간 변경해 보겠습니다 .

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {

       public static void main(String[] args) {
           List vector = new ArrayList();
           //Vector vector = new Vector();
           System.out.println("the size of the empty vector = " +  vector.size());
           vector.add("Johnny");
           vector.add("Ivy");
           vector.add("Ricky");
           System.out.println(vector);
           vector.add("Johnny");
           vector.add("Paul");
           System.out.println(vector);
           System.out.println("the size of the vector = " +  vector.size());
           //System.out.println("the first element of the vector = " + vector.firstElement());

           //here the program will print out the first appearance of "Johnny" element
           System.out.println(vector.indexOf("Johnny"));
           //program will print out the first appearance of "Johnny" element starting from the element 1
           //System.out.println(vector.indexOf("Johnny", 1));
           vector.clear();
           System.out.println("the size of the vector after clear method = " +  vector.size());

       }
   }
Vector.indexOf("Johnny", 1) 로 줄을 주석 처리했습니다 . ArrayList 클래스 의 이 변형에는 그러한 메서드가 없기 때문입니다 . 같은 이유로 vector.firstElement() 행이 주석 처리되었습니다. 다른 모든 측면에서 프로그램은 첫 번째 프로그램과 동일한 결과를 생성합니다. 물론 이러한 예에서 ArrayList가 Vector 보다 나은 이유는 명확하지 않습니다 . 이를 위해서는 스레드에 대한 더 많은 지식이 필요합니다. 여기에 이유를 나열합니다. 첫째, Vector 클래스가 동기화되어 있지만 이상하게 보이지만 완전히 스레드로부터 안전하다고 할 수는 없습니다. 사실 Vector는 전체 Vector 가 아니라 각 작업을 동기화합니다.인스턴스 자체. 이는 개별 작업이 아닌 전체 작업 세트를 동기화해야 하는 프로그램에서 문제가 될 수 있습니다. 한 스레드가 벡터를 반복하고 다른 스레드가 벡터의 인스턴스를 구조적으로 수정하는 경우 반복자는 ConcurrentModificationException 을 발생 시킵니다 . 두 스레드가 서로 다른 작업을 수행하는 경우 동시에 Vector 인스턴스 에서 작업할 수 있음이 밝혀졌습니다 . 둘째, 벡터객체에 크기 조정 가능한 배열과 동기화가 있기 때문에 클래스가 최상의 성능을 발휘하지 못합니다. 이 조합은 동기화가 필요한지 여부에 관계없이 차단 작업에 대한 추가 오버헤드를 의미합니다. 물론 이것은 성능에 영향을 미칩니다. 또한 각 작업에서 벡터를 동기화하면 각 작업에 대해 계속해서 잠금을 획득하므로 성능에 부정적인 영향을 미칩니다. 클래스의 전체 인스턴스가 동기화되면 잠금도 한 번 획득되므로 훨씬 더 효율적입니다. 셋째, 벡터는 일부 레거시 방법을 지원합니다. 예를 들어 요소(). 이 메서드는 벡터 구성 요소의 열거형을 반환합니다. 프로그래머는 여러 가지 이유로 Iterator 또는 ListIterator를 Enumeration에 가장 자주 사용합니다. 특히 Enumeration에는 remove() 메서드가 정의되어 있지 않으므로 반복 중에 목록을 구조적으로 수정할 수 없습니다. 또한 ListIterator와 달리 Enumeration은 양방향 액세스를 제공하지 않습니다. 보시 다시피 Vector 에는 몇 가지 문제가 있습니다. 여전히 List 인터페이스의 스레드 안전 구현이 필요한 경우 어떻게 합니까? 이 경우 ArrayList는 도움이 되지 않지만 예를 들어 Vector 대신 CopyOnWriteArrayList 클래스를 사용할 수 있습니다 . ArrayList 의 스레드로부터 안전한 변형으로 배치됩니다.. 컬렉션의 synchronizedList() 메서드를 사용하여 ArrayList를 동기화할 수도 있습니다 .

Vector에는 정말 몇 가지 문제가 있습니다. 왜 여전히 Java에 있고 왜 가르쳐야 합니까?

질문이 생깁니다. 왜 우리는 벡터 클래스를 공부하고 있습니까? 그리고 왜 아직 Java에서 제거되지 않았습니까? 사실 Java는 이전 버전과의 호환성 원칙을 공언합니다. 이것은 수년 전에 작성된 모든 오래된 코드가 최신 버전의 Java에서 이해될 것임을 의미합니다. 또한 Java 환경에는 수십 년 동안 지원되어 온 엔터프라이즈급 응용 프로그램이 꽤 있습니다. 작업에서 그러한 "공룡"을 처리해야 할 가능성이 매우 높으므로 비효율적인 레거시 클래스가 있는 코드와 같은 놀라움에 대비해야 합니다.