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