Arreglos
📦 Arrays
Los arrays son las estructuras de datos más simples y se usan para almacenar listas de elementos, como cadenas, números, objetos y, literalmente, cualquier cosa.
Estos elementos se almacenan secuencialmente en memoria.
Por ejemplo, si asignamos un array de 5 enteros, estos se almacenan en memoria de la siguiente manera:

Supongamos que la dirección del primer elemento en memoria es 100.
Como probablemente sepas, los enteros en Java ocupan 4 bytes de memoria.
Por lo tanto:
El segundo elemento estará en la posición 104.
El tercero en la posición 108.
Y así sucesivamente.
Acceso por índice
Por esta razón, buscar elementos en un array por su índice es rapidísimo.
Le damos un índice y el compilador sabe exactamente a qué posición de memoria acceder.
👉 La complejidad en tiempo de ejecución es \(O(1)\).

Como el cálculo de la dirección de memoria es simple, no requiere bucles ni lógica adicional.
Si necesitas acceder rápidamente a una lista de elementos, los arrays son la estructura ideal.
Redimensionamiento
En Java (y muchos lenguajes), los arrays son estáticos:
su tamaño se define al crearlos y no puede cambiar después.
¿Qué ocurre si necesitamos más espacio?
Debemos crear un nuevo array más grande y copiar los elementos del anterior en él.
👉 Este proceso tiene una complejidad de \(O(n)\) porque debemos copiar todos los elementos.

Eliminación
Eliminar elementos también depende del caso:
Si borramos el último elemento, es muy sencillo: \(O(1)\).
Pero si borramos el primer elemento, todos los demás deben desplazarse a la izquierda.
👉 Esto implica una complejidad de \(O(n)\) en el peor de los casos.

En general, las operaciones básicas sobre arrays son:
Lookup: \(O(1)\)
Insert: \(O(n)\)
Delete: \(O(n)\)
Arrays en Java
Un ejemplo simple en Java sería:
public class Main {
public static void main(String[] args) {
// Declarar un array de tamaño 5
int[] numbers = new int[5];
// Asignar valores
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;
// Recorrer y mostrar
for (int i = 0; i < numbers.length; i++) {
System.out.println("Elemento en índice " + i + ": " + numbers[i]);
}
}
}Dado que los arrays tienen un tamaño fijo, no funcionan bien cuando no sabemos cuántos elementos necesitaremos, o cuando debemos añadir/eliminar muchos elementos.
En esos casos, usaremos listas enlazadas, que veremos más adelante en el curso.
🗂️ Clase Arreglos
👉 Ejercicio:
Vas a implementar tu propia clase Arreglo en Java, que funcione como un arreglo dinámico.
Recuerda que a diferencia de los arreglos estáticos de Java, este podrá crecer automáticamente cuando insertes nuevos elementos y también permitirá eliminar valores en una posición específica.
Tu clase debe incluir los siguientes métodos:
insertar(int item): agrega un nuevo elemento al final del arreglo.Si el arreglo está lleno, crea uno más grande y copia los elementos.
eliminarEn(int indice): elimina el elemento en la posición indicada y desplaza los demás.indiceDe(int item): devuelve el índice del elemento si existe, o-1si no está en el arreglo.imprimir(): muestra el contenido actual del arreglo en consola.
⚡ Prueba tu clase con un programa principal (Main) que:
- Cree un
Arreglode tamaño inicial 3.
- Inserte los valores
10,20y30, e imprima el arreglo.
- Inserte el valor
40(el arreglo debe crecer automáticamente) e imprima de nuevo.
- Elimine el último elemento e imprima.
- Busque el índice de
10y de100e imprima el resultado.
🧮 Crear la clase
➕ Método: insertar()
➖ Método: eliminarEn()
🔍 Método: busqueda()
Arreglos dinámicos en Java: Vector vs ArrayList
Construir un arreglo dinámico “a mano” nos enseña la idea clave: cuando se llena el arreglo interno, se crea otro más grande y se copian los elementos.
Java ya trae dos clases que hacen eso por nosotros:
ArrayList(la opción moderna y preferida).Vector(clase histórica/legacy, con sincronización integrada).
Ambas viven en java.util, almacenan datos en un arreglo interno y crecen automáticamente cuando hace falta.
Diferencias esenciales (rápidas)
Crecimiento de capacidad:
ArrayListsuele crecer ~50%;Vectorcrece 100% (o por incremento fijo si lo defines).Concurrencia:
Vectorsincroniza todos sus métodos (añade sobrecosto);ArrayListno sincroniza (más rápido en un hilo).Si necesitas hilos, hoy se prefiere
ArrayList+ una estrategia de sincronización específica (por ejemploCollections.synchronizedList(...)oCopyOnWriteArrayList).
Genéricos en ArrayList
ArrayList<Integer> indica que la lista guarda objetos Integer (el wrapper de int).
También puedes usar ArrayList<String>, ArrayList<Estudiante>, etc.
Tour esencial de ArrayList
1) Importar y crear
import java.util.ArrayList;
ArrayList<Integer> lista = new ArrayList<>(); // lista vacía
System.out.println(lista); // []ArrayList<Integer>: lista deInteger(no deint).new ArrayList<>(): construye con capacidad por defecto (crecerá sola).
2) Agregar elementos (add)
lista.add(10);
lista.add(20);
lista.add(30);
System.out.println(lista); // [10, 20, 30]
// Insertar en una posición específica (desplaza lo que había)
lista.add(1, 20);
System.out.println(lista); // [10, 20, 20, 30]add(e)al final es O(1) amortizado (puede saltar a O(n) cuando toca crecer).add(i, e)en el medio/inicio suele ser O(n) (hay corrimientos).
3) Eliminar por objeto vs por índice
// Quitar por objeto: elimina la PRIMERA ocurrencia de 20
boolean ok = lista.remove(Integer.valueOf(20));
System.out.println(ok + " | " + lista); // true | [10, 20, 30]
// Quitar por índice (posición 0 = primer elemento)
int eliminado = lista.remove(0);
System.out.println(eliminado + " | " + lista); // 10 | [20, 30]- Importante:
remove(20)llamaría a la versión “por índice” (porque 20 esint). Para quitar el objeto 20, usaInteger.valueOf(20).
4) Buscar y consultar
lista.add(30); // [20, 30, 30]
System.out.println(lista.indexOf(30)); // 1 (primera ocurrencia)
System.out.println(lista.lastIndexOf(30)); // 2 (última ocurrencia)
System.out.println(lista.contains(20)); // true
System.out.println(lista.size()); // 3
System.out.println(lista.isEmpty()); // falseindexOf/lastIndexOf/containsrecorren y comparan → O(n).
5) Convertir a arreglo (toArray)
import java.util.Arrays;
Integer[] arr = lista.toArray(new Integer[0]);
System.out.println(Arrays.toString(arr)); // [20, 30, 30]- Útil cuando una API exige arreglo en vez de lista.
6) Recorrer con for-each
for (Integer x : lista) {
System.out.print(x + " ");
}
// Salida: 20 30 30
System.out.println();Complejidad (Big-O) habitual
- Acceso por índice: O(1)
add(e)al final (amortizado): O(1), con crecimientos puntuales O(n)add(i, e)/remove(i)/remove(obj)/contains/indexOf: O(n)
Si haces muchas inserciones/eliminaciones en medio, quizá una lista enlazada sea mejor; para acceso por índice y uso general,
ArrayListsuele ganar.
Buenas prácticas rápidas
Usa
ArrayListpor defecto.Si necesitas concurrencia:
Collections.synchronizedList(new ArrayList<>())para algo sencillo, oCopyOnWriteArrayListsi hay muchas lecturas y pocas escrituras.
Si ya conoces el tamaño aproximado, puedes dar capacidad inicial:
new ArrayList<>(capacidad).
Código completo (para copiar/pegar)
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 1) Crear
ArrayList<Integer> lista = new ArrayList<>();
System.out.println("Inicio: " + lista); // []
// 2) Agregar
lista.add(10);
lista.add(20);
lista.add(30);
System.out.println("Después de add: " + lista); // [10, 20, 30]
// Insertar en índice 1
lista.add(1, 20);
System.out.println("Insertando en índice 1: " + lista); // [10, 20, 20, 30]
// 3) Eliminar: por objeto vs por índice
boolean ok = lista.remove(Integer.valueOf(20)); // quita primera ocurrencia de 20
System.out.println("remove(obj 20): " + ok + " | " + lista); // true | [10, 20, 30]
int eliminado = lista.remove(0); // quita el 10
System.out.println("remove(índice 0): " + eliminado + " | " + lista); // [20, 30]
// 4) Buscar/consultar
lista.add(30); // [20, 30, 30]
System.out.println("indexOf(30): " + lista.indexOf(30)); // 1
System.out.println("lastIndexOf(30): " + lista.lastIndexOf(30)); // 2
System.out.println("contains(20): " + lista.contains(20)); // true
System.out.println("size(): " + lista.size()); // 3
System.out.println("isEmpty(): " + lista.isEmpty()); // false
// 5) toArray
Integer[] arr = lista.toArray(new Integer[0]);
System.out.println("toArray -> " + Arrays.toString(arr)); // [20, 30, 30]
// 6) Recorrer
System.out.print("Recorriendo: ");
for (Integer x : lista) System.out.print(x + " ");
System.out.println(); // 20 30 30
}
}Vector (referencia breve)
import java.util.Vector;
public class DemoVector {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>(); // sincronizado (legacy)
v.add(1);
v.add(2);
System.out.println(v); // [1, 2]
}
}Conclusión: para cursos y proyectos actuales,
ArrayListes la opción por defecto; si necesitas hilos, agrega sincronización explícita y moderna.