ArrayList de Java vs Vector

Descripción general

En este tutorial, nos centraremos en las diferencias entre las clases ArrayList y Vector. Ambos pertenecen al framework Java Collections e implementan java.útil.Interfaz de lista.

Sin embargo, estas clases tienen diferencias significativas en sus implementaciones.

¿Qué es diferente?

Como inicio rápido, presentemos las diferencias clave de ArrayList y Vector. Luego, discutiremos algunos de los puntos con más detalle:

  • sincronización: La primera diferencia importante entre estos dos. Vector está sincronizado y ArrayList no.
  • crecimiento de tamaño: Otra diferencia entre los dos es la forma en que cambian de tamaño mientras alcanzan su capacidad. El vector duplica su tamaño. Por el contrario, ArrayList aumenta solo la mitad de su longitud
  • iteración, y Vector puede usar el Iterador y la Enumeración para recorrer los elementos. Por otro lado, ArrayList solo puede usar Iterador.rendimiento
  • – En gran parte debido a la sincronización, las operaciones vectoriales son más lentas en comparación con el framework ArrayList
  • – Además, ArrayList es parte del framework Collections y se introdujo en JDK 1.2. Mientras tanto, Vector está presente en las versiones anteriores de Java como una clase heredada.

Vector

Como ya tenemos una guía extendida sobre ArrayList, no discutiremos su API y capacidades aquí. Por otro lado, presentaremos algunos detalles básicos sobre Vector.

En pocas palabras, un vector es una matriz de tamaño variable. Puede crecer y encogerse a medida que agregamos o eliminamos los elementos.

Podemos crear un vector de la manera típica:

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

El constructor predeterminado crea un vector vacío con una capacidad inicial de 10.

Agreguemos algunos valores:

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

Y, por último, vamos a recorrer los valores utilizando la interfaz del iterador:

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

O bien, podemos recorrer el Vector usando Enumeración:

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

Ahora, exploremos algunas de sus características únicas con más profundidad.

Concurrencia

Ya hemos mencionado que ArrayList y Vector son diferentes en su estrategia de concurrencia, pero echemos un vistazo más de cerca. Si nos sumergiéramos en las firmas de los métodos vectoriales, veríamos que cada una tiene la palabra clave sincronizada:

public synchronized E get(int index)

En pocas palabras, esto significa que solo un hilo puede acceder a un vector dado a la vez.

Sin embargo, en realidad, estas sincronizaciones a nivel de operación deben superponerse de todos modos con nuestra propia sincronización para operaciones compuestas.

Así que, en contraste, ArrayList toma un enfoque diferente. Sus métodos no están sincronizados y esa preocupación se separa en clases dedicadas a la concurrencia.

Por ejemplo, podemos usar CopyOnWriteArrayList o Collections.Lista sincronizada para obtener un efecto similar al Vector:

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

Rendimiento

Como ya hemos comentado anteriormente, Vector está sincronizado, lo que causa un impacto directo en el rendimiento.

Para ver la diferencia de rendimiento entre las operaciones de Vector y ArrayList, escribamos una prueba de referencia JMH simple.

En el pasado, hemos analizado la complejidad temporal de las operaciones de ArrayList, así que agreguemos los casos de prueba para Vector.

Primero, probemos el método 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);}

Configuraremos JMH para usar tres subprocesos y 10 iteraciones de calentamiento.

Y, vamos a informar sobre el tiempo promedio por operación a nivel de nanosegundos:

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

Podemos ver que ArrayList # get funciona tres veces más rápido que Vector # get.

Ahora, comparemos los resultados de la operación 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);}

E imprima los resultados:

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

Como podemos ver, para la operación contains (), el tiempo de rendimiento para Vector es mucho más largo que ArrayList.

Resumen

En este artículo, echamos un vistazo a las diferencias entre las clases Vector y ArrayList en Java. Además, también presentamos características vectoriales con más detalles.

Como de costumbre, el código completo de este artículo está disponible en GitHub.

Comience con Spring 5 y Spring Boot 2, a través del curso Learn Spring:

>> ECHA UN VISTAZO AL CURSO



+