Java ArrayList vs Vector

Java ArrayList vs Vector

1. Visão geral

Neste tutorial,we’re going to focus on the differences between the ArrayList and Vector classes. Ambos pertencem ao Java Collections Framework e implementam a interfacejava.util.List.

No entanto,these classes have significant differences em suas implementações.

2. O que é diferente?

Como um início rápido, vamos apresentar as principais diferenças deArrayList and Vector. Em seguida, discutiremos alguns dos pontos com mais detalhes:

  • sincronização - a primeira grande diferença entre esses dois. Vector está sincronizado eArrayList  não.

  • aumento de tamanho - Outra diferença entre os dois é a maneira como eles redimensionam enquanto atingem sua capacidade. The Vector doubles its size. In contrast, ArrayList increases only by half of its length

  • iteração - EVector can use Iterator and Enumeration to traverse over the elements.  Por outro lado,ArrayList só pode usarIterator.

  • desempenho - principalmente devido à sincronização, as operações deVector são mais lentas quando comparadas aArrayList

  • framework - Além disso,ArrayList faz parte do framework de coleções e foi introduzido no JDK 1.2. Enquanto isso,Vector está presente nas versões anteriores do Java como uma classe legada.

3. Vector

Como já temos um guia estendido sobre ArrayList,, não discutiremos sua API e recursos aqui. Por outro lado, apresentaremos alguns detalhes principais sobreVector.

Simply put, a Vector is a resizable array. Pode crescer e encolher à medida que adicionamos ou removemos os elementos.

Podemos criar um vetor da maneira típica:

Vector vector = new Vector<>();

O construtor padrão cria umVector vazio com uma capacidade inicial de 10.

Vamos adicionar alguns valores:

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

E, finalmente, vamos iterar os valores usando a interfaceIterator:

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

Ou podemos percorrerVector usandoEnumeration:

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

Agora, vamos explorar alguns de seus recursos exclusivos com mais profundidade.

4. Concorrência

Já mencionamos queArrayList eVector são diferentes em sua estratégia de simultaneidade, mas vamos dar uma olhada mais de perto. Se mergulharmos nas assinaturas do métodoVector’s, veríamos que cada uma tem a palavra-chave sincronizada:

public synchronized E get(int index)

Simplificando,this means that only one thread can access a given vector at a time.

Na verdade, porém, essas sincronizações de nível de operação precisam ser sobrepostas de qualquer maneira com nossa própria sincronização para operações compostas.

Portanto, em contraste,ArrayList adota uma abordagem diferente. Seus métodos sãonot sincronizados e essa preocupação é separada em classes que são dedicadas à simultaneidade.

Por exemplo, podemos usarCopyOnWriteArrayList ouCollections.synchronizedList para obter um efeito semelhante aVector:

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

5. atuação

Como já discutimos acima,Vector is synchronized which causes a direct impact on performance.

Para ver a diferença de desempenho entreVector versusArrayList operações, vamos escrever um testeJMH benchmark simples.

No passado, vimosthe time complexity of ArrayList‘s operations, então vamos adicionar os casos de teste paraVector.

First, vamos testar o métodoget():

@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);
}

Vamos configurar o JMH para usar três threads e 10 iterações de aquecimento.

E vamos relatar o tempo médio por operação no nível de nanossegundos:

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

Podemos ver queArrayList#get works about three times faster than Vector#get.

Agora, vamos comparar os resultados da operaçãocontains():

@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);
}

E imprima os resultados:

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

Como podemos ver, para a operaçãocontains(), o tempo de desempenho paraVector é muito maior do queArrayList.

6. Sumário

Neste artigo, vimos as diferenças entre as classesVectoreArrayList em Java. Além disso, também apresentamos os recursos deVector em mais detalhes.

Como de costume, o código completo deste artigo está disponívelover on GitHub.