Java ArrayList vs Vector

przegląd

w tym samouczku skupimy się na różnicach między klasami ArrayList i vector. Oba należą do Java Collections Framework i implementują Javę.util.Interfejs listy.

jednak klasy te mają znaczące różnice w swoich implementacjach.

czym się różni?

na szybki początek przedstawmy kluczowe różnice ArrayList i Vector. Następnie omówimy niektóre z punktów bardziej szczegółowo:

  • synchronizacja-pierwsza poważna różnica między tymi dwoma. Vector jest zsynchronizowany, a ArrayList nie.
  • wzrost rozmiaru-inną różnicą między nimi jest sposób, w jaki zmieniają rozmiar podczas osiągania ich pojemności. Wektor podwaja swoją wielkość. W przeciwieństwie do tego, ArrayList zwiększa tylko o połowę swojej długości
  • iteracja-a Vector może używać iteratora i wyliczenia do przechodzenia przez elementy. Z drugiej strony, ArrayList może używać tylko iteratora.
  • wydajność-głównie ze względu na synchronizację, operacje wektorowe są wolniejsze w porównaniu z frameworkiem ArrayList
  • – ponadto ArrayList jest częścią frameworku Collections i został wprowadzony w JDK 1.2. W międzyczasie Vector jest obecny we wcześniejszych wersjach Javy jako klasa legacy.

Vector

ponieważ mamy już Rozszerzony przewodnik na temat ArrayList,nie będziemy tutaj omawiać jego API i możliwości. Z drugiej strony, przedstawimy kilka podstawowych szczegółów dotyczących wektora.

Mówiąc najprościej, wektor jest tablicą z możliwością zmiany rozmiaru. Może rosnąć i kurczyć się, gdy dodajemy lub usuwamy elementy.

możemy stworzyć wektor w typowy sposób:

Vector<String> vector = new Vector<>();

domyślny konstruktor tworzy pusty wektor o początkowej pojemności 10.

dodajmy kilka wartości:

vector.add("baeldung");vector.add("Vector");vector.add("example");

i na koniec, przejdźmy przez wartości za pomocą interfejsu iteratora:

Iterator<String> iterator = vector.iterator();while (iterator.hasNext()) { String element = iterator.next(); // ...}

lub możemy przemierzać Wektor za pomocą wyliczenia:

Enumeration e = vector.elements();while(e.hasMoreElements()) { String element = e.nextElement(); // ... }

teraz przyjrzyjmy się bliżej ich unikalnym funkcjom.

współbieżność

wspomnieliśmy już, że ArrayList i Vector różnią się w swojej strategii współbieżności, ale przyjrzyjmy się im bliżej. Gdybyśmy zgłębiali sygnatury metody wektora, zobaczylibyśmy, że każda z nich ma zsynchronizowane słowo kluczowe:

public synchronized E get(int index)

Mówiąc najprościej, oznacza to, że tylko jeden wątek może uzyskać dostęp do danego wektora naraz.

tak naprawdę, ta synchronizacja na poziomie operacji i tak musi być nakładana na naszą własną synchronizację dla operacji złożonych.

w przeciwieństwie do tego, ArrayList ma inne podejście. Jego metody nie są zsynchronizowane, a problem ten jest podzielony na klasy poświęcone współbieżności.

na przykład możemy użyć Copyonwritearraylist lub Collections.zsynchronizowana lista, aby uzyskać podobny efekt do Vector:

vector.get(1); // synchronizedCollections.synchronizedList(arrayList).get(1); // also synchronized

wydajność

jak już omówiliśmy powyżej, Vector jest zsynchronizowany, co powoduje bezpośredni wpływ na wydajność.

aby zobaczyć różnicę wydajności między operacjami wektorowymi a operacjami ArrayList, napiszmy prosty test porównawczy JMH.

w przeszłości przyjrzeliśmy się złożoności czasowej operacji ArrayList, więc dodajmy przypadki testowe dla wektora.

najpierw przetestujmy metodę get() :

@Benchmarkpublic Employee testGet(ArrayListBenchmark.MyState state) { return state.employeeList.get(state.employeeIndex);}@Benchmarkpublic Employee testVectorGet(ArrayListBenchmark.MyState state) { return state.employeeVector.get(state.employeeIndex);}

skonfigurujemy JMH do używania trzech wątków i 10 iteracji rozgrzewki.

i, przedstawmy średni czas na operację na poziomie nanosekund:

Benchmark Mode Cnt Score Error UnitsArrayListBenchmark.testGet avgt 20 9.786 ± 1.358 ns/opArrayListBenchmark.testVectorGet avgt 20 37.074 ± 3.469 ns/op

widzimy, że ArrayList # get działa około trzy razy szybciej niż Vector # get.

teraz porównajmy wyniki operacji contains() :

@Benchmarkpublic boolean testContains(ArrayListBenchmark.MyState state) { return state.employeeList.contains(state.employee);}@Benchmarkpublic boolean testContainsVector(ArrayListBenchmark.MyState state) { return state.employeeVector.contains(state.employee);}

i wydrukować wyniki:

Benchmark Mode Cnt Score Error UnitsArrayListBenchmark.testContains avgt 20 8.665 ± 1.159 ns/opArrayListBenchmark.testContainsVector avgt 20 36.513 ± 1.266 ns/op

jak widzimy, dla operacji contains() czas działania dla Vector jest znacznie dłuższy niż ArrayList.

podsumowanie

w tym artykule przyjrzeliśmy się różnicom między klasami Vector i ArrayList w Javie. Dodatkowo bardziej szczegółowo przedstawiliśmy funkcje wektorowe.

jak zwykle, Pełny kod tego artykułu jest dostępny na Githubie.

zacznij od Spring 5 i Spring Boot 2, korzystając z kursu Learn Spring:

>> sprawdź kurs



+