Java ArrayList vs Vector

Prezentare generală

în acest tutorial, ne vom concentra pe diferențele dintre clasele ArrayList și Vector. Ambele fac parte din cadrul colecțiilor Java și implementează java.util.Interfață listă.

cu toate acestea, aceste clase au diferențe semnificative în implementările lor.

ce este diferit?

ca un început rapid, să prezentăm diferențele cheie dintre ArrayList și Vector. Apoi, vom discuta câteva dintre puncte în detaliu:

  • sincronizare – prima diferență majoră între aceste două. Vector este sincronizat și ArrayList nu este.
  • creșterea dimensiunii – o altă diferență între cele două este modul în care se redimensionează în timp ce își ating capacitatea. Vectorul își dublează dimensiunea. În schimb, ArrayList crește doar cu jumătate din lungimea sa
  • iterație – și Vector poate folosi Iterator și enumerare pentru a traversa peste elemente. Pe de altă parte, ArrayList poate folosi doar Iterator.
  • performanță – în mare parte datorită sincronizării, operațiile vectoriale sunt mai lente în comparație cu ArrayList
  • framework – de asemenea, ArrayList face parte din cadrul colecțiilor și a fost introdus în JDK 1.2. Între timp, Vector este prezent în versiunile anterioare ale Java ca o clasă moștenită.

Vector

deoarece avem deja un ghid extins despre ArrayList, nu vom discuta API-ul și capacitățile sale aici. Pe de altă parte, vom prezenta câteva detalii de bază despre Vector.

mai simplu spus, un Vector este o matrice redimensionabilă. Se poate dezvolta și micșora pe măsură ce adăugăm sau eliminăm elementele.

putem crea un vector în mod tipic:

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

constructorul implicit creează un Vector gol cu o capacitate inițială de 10.

să adăugăm câteva valori:

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

și, în sfârșit, să iterăm prin valori utilizând interfața Iterator:

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

sau, putem traversa vectorul folosind enumerarea:

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

acum, să explorăm câteva dintre caracteristicile lor unice în profunzime.

concurență

am menționat deja că ArrayList și Vector sunt diferite în strategia lor de concurență, dar să aruncăm o privire mai atentă. Dacă ar fi să ne scufundăm în semnăturile metodei Vector, am vedea că fiecare are cuvântul cheie sincronizat:

public synchronized E get(int index)

pur și simplu, acest lucru înseamnă că un singur fir poate accesa un vector dat la un moment dat.

într-adevăr, totuși, aceste sincronizări la nivel de operație trebuie oricum suprapuse cu propria noastră sincronizare pentru operații compuse.

deci, în contrast, ArrayList are o abordare diferită. Metodele sale nu sunt sincronizate și această preocupare este separată în clase care sunt dedicate concurenței.

de exemplu, putem folosi CopyOnWriteArrayList sau colecții.synchronizedList pentru a obține un efect similar cu Vector:

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

performanță

așa cum am discutat deja mai sus, vectorul este sincronizat, ceea ce determină un impact direct asupra performanței.

pentru a vedea diferența de performanță dintre operațiunile Vector versus ArrayList, să scriem un simplu test de referință JMH.

în trecut, ne-am uitat la complexitatea timpului operațiilor ArrayList, deci să adăugăm cazurile de testare pentru Vector.

mai întâi, să testăm metoda 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);}

vom configura JMH pentru a utiliza trei fire și 10 iterații warmup.

și, să raportăm timpul mediu pe operație la nivelul nanosecundelor:

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

putem vedea că ArrayList # get funcționează de aproximativ trei ori mai repede decât Vector#get.

acum, să comparăm rezultatele operației conține() :

@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 imprimați rezultatele:

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

după cum putem vedea, pentru operația contains (), timpul de performanță pentru Vector este mult mai lung decât ArrayList.

rezumat

în acest articol, am analizat diferențele dintre clasele Vector și ArrayList din Java. În plus, am prezentat și caracteristici vectoriale în mai multe detalii.

ca de obicei, codul complet pentru acest articol este disponibil peste pe GitHub.

începeți cu Spring 5 și Spring Boot 2, prin cursul Learn Spring:

>> verificați cursul



+