John Squirrels
Ниво
San Francisco

Java Vector

Публикувано в групата
Вероятно вече сте срещали масиви в Java и знаете, че един от основните им недостатъци е постоянството на размера. След като създадете масив с определен размер, не можете да го промените по-късно. Има няколко рамкови класа на Java Collection в езика Java, които решават този проблем. Един от тях е Java Vector Class. Ще бъде обсъдено в тази статия.

Какво е векторен клас

Както писахме в предговора, класът Vector от Java Collection Framework елиминира проблема със статичния размер на масивите. Java Vector е вид динамичен масив и може да расте or да се свива по размер. Използвайки класа за колекция Vector , можем да съхраняваме група от елементи като прости обекти и да ги манипулираме чрез различните методи. Класът Vector е достъпен от пакета java.util . По този начин Vector в Java може да се използва, ако не знаете размера на масива предварително or ако имате нужда от "масив", който може да променя размерите през целия живот на програмата. Веднага трябва да се каже, че Векторътклас вече е доста стар и по-късно се появиха колекции, които могат да го заменят в по-голямата част от случаите. Популярният „аналог“ на Java Vector е класът ArrayList . Най-важната разлика между тези класове един от друг е, че Vector е синхронизиран, докато ArrayList не е. Ще говорим за други разлики между тези два класа и по-модерни аналози на класа Vector малко по-късно в раздела „Какво не е наред с класа Vector“.

Векторни методи на Java

Ето векторни методи на Java:
  • void add(int index, Object element) вмъква посочения елемент в определената позиция на вектора.

  • boolean add(Object o) добавя посочения елемент към края на вектора.

  • boolean addAll(Collection c) добавя всички елементи в указаната колекция към края на вектора в реда, в който са върнати от посочения итератор на колекция.

  • boolean addAll(int index, Collection c) вмъква всички елементи в определената колекция във вектора на посочената позиция.

  • void addElement(Object obj) добавя посочения компонент към края на този вектор, увеличавайки размера му с единица.

  • int capacity() връща текущия капацитет на този вектор.

  • void clear() премахва всички елементи от този вектор.

  • Object clone() връща клонинг на този вектор.

  • boolean съдържа (Object elem) тества дали посоченият обект е компонент в този вектор.

  • boolean containsAll(Collection c) връща true, ако векторът съдържа всички елементи от указаната колекция.

  • void copyInto(Object[] anArray) копира компонентите на този вектор в посочения масив.

  • Обект elementAt(int index) връща компонента на посочения индекс.

  • Enumeration elements() връща изброяване на компонентите на този вектор.

  • void secureCapacity(int minCapacity) увеличава капацитета на този вектор, ако е необходимо, за да гарантира, че той може да побере поне броя компоненти, зададен от аргумента за минимален капацитет.

  • boolean equals(Object o) сравнява посочения обект с този вектор.

  • Object firstElement() връща първия компонент (елемент с индекс 0) на този вектор.

  • Object get(int index) връща елемента на посочената позиция в този вектор.

  • int hashCode() връща стойността на хеш codeа за този вектор.

  • int indexOf(Object elem) търси първото срещане на дадения аргумент, като тества за equalsство с помощта на метода equals.

  • int indexOf(Object elem, int index) търси първото срещане на дадения аргумент, започвайки от index, и тества за equalsство с помощта на метода equals.

  • void insertElementAt(Object obj, int index) вмъква посочения обект като компонент в този вектор при посочения индекс.

  • boolean isEmpty() тества този вектор за липсващи компоненти.

  • Object lastElement() връща последния компонент на вектора.

  • int lastIndexOf(Object elem) връща индекса на последното срещане на посочения обект в този вектор.

  • int lastIndexOf(Object elem, int index) търси назад посочения обект, започвайки от посочения индекс, и връща индекса към него.

  • Object remove(int index) премахва елемента на посочената позиция в този вектор.

  • boolean remove(Object o) премахва първото срещане на посочения елемент в този вектор. Ако векторът не съдържа елемент, той не се променя.

  • boolean removeAll(Collection c) премахва всички елементи от вектора, които се съдържат в указаната колекция.

  • void removeAllElements() премахва всички компоненти от вектора и задава размера му на нула.

  • boolean removeElement(Object obj) премахва първото (с най-нисък индекс) срещане на аргумента от този вектор.

  • void removeElementAt(int index) премахва елемент по индекс.

  • protected void removeRange(int fromIndex, int toIndex) премахва от този списък всички елементи, чийто индекс е между fromIndex, включително, и toIndex, изключително.

  • boolean retainAll(Collection c) запазва само елементите във вектора, които се съдържат в указаната колекция.

  • 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() намалява капацитета на този вектор до текущия размер на вектора.

Пример за вектор на Java


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 [Джони, Айви, Рики] [Джони, Айви, Рики, Джони, Пол] размерът на вектора = 5 първият елемент на вектора = Джони 0 3 размерът на вектора след изчистване метод = 0

Какво не е наред с Vector Class?

Според documentацията на клас Java Vector , ако не се нуждаете от безопасна за нишки реализация във вашата програма, се препоръчва да използвате ArrayList instead of Vector (по-ефективен участник на Collection Framework). Нека променим малко горния пример, използвайки класа ArrayList instead of Vector .

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 едновременно, ако изпълняват различни операции. Второ, Векторъткласът няма най-добрата производителност, защото неговите обекти имат масив с възможност за промяна на размера и синхронизация. Тази комбинация означава допълнителни разходи за блокиране на операции, независимо дали е необходима синхронизация or не. Разбира се, това се отразява на производителността. В допълнение, синхронизирането на вектора при всяка операция също има отрицателен ефект върху производителността, тъй като ще придобиваме заключване отново и отново за всяка операция. Ако цялото копие на класа беше синхронизирано, тогава заключването също щеше да бъде получено веднъж, което е много по-ефективно. Трето, Vector поддържа някои наследени методи. Например elements(). Този метод връща изброяване на компонентите на вектора. Програмистите най-често използват Iterator or ListIterator за изброяване и поради редица причини. По-специално, Enumeration няма дефиниран метод за премахване () , което означава, че списъкът не може да бъде структурно модифициран по време на итерация. Освен това, за разлика от ListIterator, Enumeration не предлага двупосочен достъп. Както можете да видите, Vector има доста проблеми. Какво ще стане, ако все още се нуждаете от безопасна за нишки реализация на интерфейс List? В този случай ArrayList няма да помогне, но можете да използвате например класа CopyOnWriteArrayList instead of Vector ; той е позициониран като безопасен за нишки вариант на ArrayList. Можете също да синхронизирате ArrayList с помощта на метода Collections synchronizedList() .

Vector наистина има някои проблеми... защо все още е в Java и защо трябва да се преподава?

Възниква въпросът: защо изобщо изучаваме класа Vector ? И защо още не е премахнат от Java? Факт е, че Java изповядва принципа на обратната съвместимост. Това означава, че целият стар code, написан преди много години, ще бъде разбран от съвременните версии на Java. В допълнение, има доста applications на корпоративно ниво в средата на Java, които се поддържат от десетилетия. Напълно възможно е да се сблъскате с такъв „динозавър“ в работата си, така че трябва да сте подготвени за изненади, като например code с неефективни наследени класове.
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION