Saltar al contenido principal

ArrayList

Hasta ahora hemos trabajado con variables que nos permiten guardar un único valor.

Por ejemplo:

String nombre = "Ana";

int edad = 20;

También hemos visto los arrays, que permiten guardar varios valores del mismo tipo.

Por ejemplo:

String[] nombres = {"Ana", "Luis", "Marta"};

Sin embargo, los arrays tienen un tamaño fijo.

Si creamos:

String[] nombres = new String[3];

el array tendrá exactamente 3 posiciones.

No podemos añadir una cuarta posición cuando el array ya está lleno.

Existe una manera en la que:

  • Importamos Arrays.
  • Creamos un nuevo array nuevo que es una copia del original pero con un hueco más (usando copyOf()).
  • En la nueva última posición (original.length) cplocamos ese nuevo elemento.
import java.util.Arrays;

int[] original = {1, 2, 3};
int nuevoElemento = 4;

int[] nuevo = Arrays.copyOf(original, original.length + 1);
nuevo[original.length] = nuevoElemento;

Sin embargo, existe otra manera más cómoda para trabajar con colecciones cuyo tamaño pueda cambiar durante la ejecución del programa: ArrayList.

Un ArrayList es una estructura que permite almacenar varios elementos y modificar su tamaño dinámicamente.

Podemos imaginarlo como una lista:

ArrayList

┌─────┬─────┬─────┐
│ Eva │ Luis│Maria│
└─────┴─────┴─────┘

Y podemos añadir nuevos elementos:

┌─────┬─────┬─────┬──────┐
│ Eva │ Luis│Maria│ Pedro │
└─────┴─────┴─────┴──────┘

También podemos eliminar elementos, buscarlos o recorrer toda la lista.


Importar ArrayList

ArrayList forma parte de las colecciones de Java.

Para poder utilizarlo debemos importar:

import java.util.ArrayList;

Crear un ArrayList

Para crear un ArrayList utilizamos:

ArrayList<Tipo> nombre = new ArrayList<>();

Por ejemplo, para crear una lista de String:

ArrayList<String> nombres = new ArrayList<>();

Podemos visualizarlo así:

ArrayList<String>

nombres

┌────┬────┬────┐
│ │ │ │
└────┴────┴────┘

Al principio la lista está vacía, y muy importante, no necesita que le indiquemos cuántos elementos tendrá la lista.

También podemos crear listas de otros tipos.

Por ejemplo:

ArrayList<Integer> edades = new ArrayList<>();

O:

ArrayList<Double> precios = new ArrayList<>();

El tipo que escribimos entre < > indica qué tipo de elementos podemos guardar.


ArrayList y tipos primitivos

Cuando utilizamos ArrayList, no podemos utilizar directamente tipos primitivos como:

int
double
boolean

En su lugar utilizamos sus clases equivalentes:

int       → Integer

double → Double

boolean → Boolean

Por ejemplo:

Incorrecto:

ArrayList<int> edades;

Correcto:

ArrayList<Integer> edades;

Java se encarga automáticamente de convertir entre int e Integer cuando sea necesario.


Añadir elementos

Para añadir elementos a un ArrayList utilizamos:

.add()

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Maria");

Ahora nuestra lista contiene:

┌─────┬──────┬───────┐
│ Eva │ Luis │ Maria │
└─────┴──────┴───────┘

Cada vez que utilizamos:

add()

el elemento se añade al final de la lista.

Por ejemplo:

nombres.add("Pedro");

Ahora tenemos:

┌─────┬──────┬───────┬───────┐
│ Eva │ Luis │ Maria │ Pedro │
└─────┴──────┴───────┴───────┘

Posiciones de un ArrayList

Al igual que ocurre con los arrays, las posiciones de un ArrayList empiezan en 0.

Por ejemplo:

Índice

0 1 2 3

┌─────┬──────┬───────┬───────┐
│ Eva │ Luis │ Maria │ Pedro │
└─────┴──────┴───────┴───────┘

Por lo tanto:

posición 0 → Eva

posición 1 → Luis

posición 2 → Maria

posición 3 → Pedro

Esto será importante cuando queramos buscar, modificar o eliminar elementos.


Añadir elementos en una posición concreta

Además de añadir elementos al final, podemos indicar la posición donde queremos añadirlo.

Para ello utilizamos:

add(posicion, elemento)

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Pedro");

Tenemos:

┌─────┬──────┬───────┐
│ Eva │ Luis │ Pedro │
└─────┴──────┴───────┘

Ahora podemos añadir "Maria" en la posición 1:

nombres.add(1, "Maria");

El resultado será:

┌─────┬───────┬──────┬───────┐
│ Eva │ Maria │ Luis │ Pedro │
└─────┴───────┴──────┴───────┘

Los elementos que estaban después de esa posición se desplazan.


Obtener un elemento

Para obtener un elemento de una posición concreta utilizamos:

.get()

Por ejemplo:

String nombre = nombres.get(1);

La posición 1 contiene "Luis".

Por lo tanto:

System.out.println(nombre);

mostrará:

Luis

Podemos visualizarlo:

  0       1        2

┌─────┬──────┬───────┐
│ Eva │ Luis │ Maria │
└─────┴──────┴───────┘

get(1)

También podemos utilizar directamente:

System.out.println(nombres.get(0));

que mostrará:

Eva

Modificar un elemento

Para cambiar el valor de una posición utilizamos:

.set()

La sintaxis es:

set(posicion, nuevoValor)

Por ejemplo, tenemos:

┌─────┬──────┬───────┐
│ Eva │ Luis │ Maria │
└─────┴──────┴───────┘

Podemos cambiar "Luis" por "Carlos":

nombres.set(1, "Carlos");

Ahora tenemos:

┌─────┬────────┬───────┐
│ Eva │ Carlos │ Maria │
└─────┴────────┴───────┘

Es importante distinguir:

add()

Añade un nuevo elemento

set()

Modifica un elemento existente

Eliminar elementos

Para eliminar elementos podemos utilizar:

remove()

Podemos eliminar utilizando su posición.

Por ejemplo, tenemos:

  0       1        2

┌─────┬──────┬───────┐
│ Eva │ Luis │ Carla │
└─────┴──────┴───────┘

Podemos eliminar "Luis" utilizando su posición:

nombres.remove(1);

Ahora tenemos:

┌─────┬───────┐
│ Eva │ Carla │
└─────┴───────┘

Los elementos posteriores se desplazan.

Antes:

0 → Eva

1 → Luis

2 → Carla

Después:

0 → Ana

1 → Carla

Eliminar un elemento por su valor

También podemos utilizar remove() indicando el objeto que queremos eliminar.

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Carla");

nombres.remove("Luis");

Ahora la lista será:

┌─────┬───────┐
│ Eva │ Carla │
└─────┴───────┘

Por tanto, podemos utilizar:

remove(posicion)

para eliminar mediante su posición.

O:

remove(elemento)

para eliminar mediante su valor.


Cuidado con remove() en Integer

Cuando trabajamos con ArrayList<Integer>, debemos tener cuidado con remove().

Por ejemplo:

ArrayList<Integer> numeros = new ArrayList<>();

numeros.add(10);
numeros.add(20);
numeros.add(30);

Si hacemos:

numeros.remove(1);

Java interpreta 1 como una posición.

Por lo tanto, eliminará:

10   20   30

1

y quedará:

10   30

Si queremos eliminar el número 20 por su valor, podemos utilizar:

numeros.remove(Integer.valueOf(20));

Ahora Java sabe que queremos eliminar el objeto Integer cuyo valor es 20.


Buscar elementos

Podemos comprobar si un ArrayList contiene un determinado elemento utilizando:

contains()

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Carla");

Podemos preguntar:

nombres.contains("Luis");

El resultado será:

true

Porque "Luis" está dentro de la lista.

En cambio:

nombres.contains("Pedro");

devolverá:

false

porque "Pedro" no está en la lista.

Podemos utilizarlo dentro de un if:

if (nombres.contains("Luis")) {

System.out.println("Luis está en la lista");

}

Salida:

Luis está en la lista

Buscar la posición de un elemento

Si además de saber si existe un elemento queremos conocer su posición, podemos utilizar:

indexOf()

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Juan");
nombres.add("Maria");

Podemos hacer:

int posicion = nombres.indexOf("Juan");

El resultado será:

1

Porque "Juan" está en la posición 1.

Podemos visualizarlo:

  0       1        2

┌─────┬──────┬───────┐
│ Eva │ Juan │ Maria │
└─────┴──────┴───────┘

indexOf()

1

Si el elemento no existe, indexOf() devuelve:

-1

Por ejemplo:

int posicion = nombres.indexOf("Pedro");

System.out.println(posicion);

Salida:

-1

Por eso podemos utilizar:

if (nombres.indexOf("Luis") != -1) {

System.out.println("Luis está en la lista");

}

Recorrer un ArrayList

Una de las operaciones más habituales será recorrer todos los elementos de un ArrayList.

Podemos hacerlo de diferentes maneras. Una de ellas es utilizar un bucle for tradicional.

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Carla");

Podemos recorrerlo así:

for (int i = 0; i < nombres.size(); i++) {

System.out.println(nombres.get(i));

}

La salida será:

Eva
Luis
Carla

Vamos a entenderlo paso a paso.

size() nos indica cuántos elementos tiene la lista:

nombres.size()

En este caso:

3

Es equivalente al length cuando usamos arrays normales.

Por lo tanto:

i < nombres.size()

equivale a:

i < 3

Los valores de i serán:

0
1
2

Y utilizamos:

nombres.get(i)

para obtener el elemento de cada posición.

Podemos verlo así:

i = 0 → nombres.get(0) → Eva

i = 1 → nombres.get(1) → Luis

i = 2 → nombres.get(2) → Carla

Recorrer con for-each

También podemos utilizar un for-each.

Por ejemplo:

for (String nombre : nombres) {

System.out.println(nombre);

}

La salida será:

Eva
Luis
Carla

Esta forma suele ser más sencilla cuando solamente queremos recorrer los elementos y no necesitamos conocer su posición.

Podemos entenderlo como:

Para cada String llamado nombre
dentro de nombres:

mostrar nombre

size() frente a length

Cuando trabajamos con arrays utilizamos:

array.length

Por ejemplo:

String[] nombres = {"Ana", "Luis", "Marta"};

System.out.println(nombres.length);

En un ArrayList utilizamos:

arrayList.size()

Por ejemplo:

ArrayList<String> nombres = new ArrayList<>();

nombres.add("Eva");
nombres.add("Luis");
nombres.add("Carla");

System.out.println(nombres.size());

El resultado será:

3

Ejemplo completo

Vamos a crear un pequeño programa para gestionar una lista de alumnos.

Primero importamos ArrayList:

import java.util.ArrayList;

Creamos nuestra lista:

ArrayList<String> alumnos = new ArrayList<>();

Añadimos algunos alumnos:

alumnos.add("Pep");
alumnos.add("Jose");
alumnos.add("Marta");

Ahora podemos mostrar la lista:

System.out.println(alumnos);

Obtendremos algo parecido a:

[Pep, Jose, Marta]

Podemos comprobar si un alumno está en la lista:

if (alumnos.contains("Josa")) {

System.out.println("Jose está matriculado");

}

Podemos buscar su posición:

int posicion = alumnos.indexOf("Jose");

System.out.println("Jose está en la posición " + posicion);

Podemos eliminarlo:

alumnos.remove("Jose");

Y finalmente podemos recorrer los alumnos restantes:

for (String alumno : alumnos) {

System.out.println(alumno);

}

Resumen de las operaciones

Podemos visualizar las operaciones principales:

                    ArrayList


┌───────────────┼────────────────┐
↓ ↓ ↓
Crear Añadir Eliminar
│ │ │
↓ ↓ ↓
new ArrayList add() remove()


┌────────┴────────┐
↓ ↓
Buscar Recorrer
│ │
┌──────┴──────┐ ↓
↓ ↓ for-each
contains() indexOf()

Las operaciones que debemos recordar principalmente son:

add()       → añadir

remove() → eliminar

contains() → comprobar si existe

indexOf() → buscar posición

get() → obtener elemento

set() → modificar elemento

size() → conocer el número de elementos