Java >> Java tutorial >  >> Tag >> ArrayList

Java ArrayList vs Vector

1. Oversigt

I dette selvstudie skal vi fokusere på forskellene mellem ArrayList og Vektor klasser . De tilhører begge Java Collections Framework og implementerer java.util.List grænseflade.

Men disse klasser har betydelige forskelle i deres implementeringer.

2. Hvad er anderledes?

Lad os som en hurtig start præsentere de vigtigste forskelle ved ArrayList og Vektor. Derefter vil vi diskutere nogle af punkterne mere detaljeret:

  • synkronisering – Den første store forskel mellem disse to. Vektor er synkroniseret og ArrayList  er det ikke.
  • Størrelsesvækst – En anden forskel mellem de to er måden, de ændrer størrelse på, mens de når deres kapacitet. Vektoren fordobler størrelsen. I modsætning hertil, ArrayList  øges kun med halvdelen af ​​sin længde
  • iteration – Og Vektor kan bruge Iterator og Optælling at krydse elementerne. På den anden side, ArrayList kan kun bruge Iterator .
  • ydelse – Hovedsageligt på grund af synkronisering, Vektor operationer er langsommere sammenlignet med ArrayList
  • ramme – også ArrayList er en del af samlingsrammen og blev introduceret i JDK 1.2. I mellemtiden Vektor er til stede i de tidligere versioner af Java som en ældre klasse.

3. Vektor

Da vi allerede har en udvidet vejledning om ArrayList, vi vil ikke diskutere dets API og muligheder her. På den anden side vil vi præsentere nogle kernedetaljer om Vektor .

Simpelt sagt, en vektor er en matrix, der kan ændres størrelse . Det kan vokse og skrumpe, efterhånden som vi tilføjer eller fjerner elementerne.

Vi kan skabe en vektor på typisk vis:

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

Standardkonstruktøren opretter en tom vektor med en startkapacitet på 10.

Lad os tilføje et par værdier:

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

Og endelig, lad os iterere gennem værdierne ved at bruge Iterator grænseflade:

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

Eller vi kan krydse vektoren ved hjælp af Optælling :

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

Lad os nu udforske nogle af deres unikke funktioner mere i dybden.

4. Samtidighed

Vi har allerede nævnt den ArrayList og Vektor er forskellige i deres samtidighedsstrategi, men lad os se nærmere. Hvis vi skulle dykke ned i Vector's metodesignaturer, vil vi se, at hver har det synkroniserede søgeord:

public synchronized E get(int index)

Kort sagt, det betyder, at kun én tråd kan få adgang til en given vektor ad gangen .

I virkeligheden skal disse synkroniseringer på operationsniveau alligevel overlejres med vores egen synkronisering til sammensatte operationer.

Så i modsætning hertil, ArrayList tager en anden tilgang. Dens metoder er ikke synkroniseret, og den bekymring er opdelt i klasser, der er dedikeret til samtidighed.

For eksempel kan vi bruge CopyOnWriteArrayList eller Collections.synchronizedList for at få en lignende effekt som Vector :

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

5. Ydeevne

Som vi allerede har diskuteret ovenfor,Vektor er synkroniseret, hvilket forårsager en direkte indvirkning på ydeevnen .

For at se ydeevneforskellen mellem Vektor kontra ArrayList  operationer, lad os skrive en simpel JMH benchmark test.

Tidligere har vi set på tidskompleksiteten af ​​ArrayList 's operationer, så lad os tilføje testcaserne for Vector.

Først , lad os teste get() metode:

@Benchmark
public Employee testGet(ArrayListBenchmark.MyState state) {
    return state.employeeList.get(state.employeeIndex);
}

@Benchmark
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
    return state.employeeVector.get(state.employeeIndex);
}

Vi konfigurerer JMH til at bruge tre tråde og 10 opvarmningsgentagelser.

Og lad os rapportere om den gennemsnitlige tid pr. operation på nanosekundniveau:

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

Vi kan se det ArrayList#get virker cirka tre gange hurtigere end Vector#get .

Lad os nu sammenligne resultaterne af contains() operation:

@Benchmark
public boolean testContains(ArrayListBenchmark.MyState state) {
    return state.employeeList.contains(state.employee);
}

@Benchmark
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
    return state.employeeVector.contains(state.employee);
}

Og print resultaterne ud:

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

Som vi kan se, for contains() operation, ydeevnetiden for Vektor er meget længere end ArrayList .

6. Resumé

I denne artikel har vi set på forskellene mellem vektoren og ArrayList klasser i Java. Derudover præsenterede vi også Vektor funktioner i flere detaljer.

Som sædvanlig er den komplette kode til denne artikel tilgængelig over GitHub.


Java tag