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
nuevoque es una copia deloriginalpero con un hueco más (usandocopyOf()). - 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