📦 ¿Qué es un array en Java?
Un array (también llamado arreglo o vector) es una estructura de datos que almacena una colección de elementos del mismo tipo en posiciones consecutivas de memoria. Cada elemento se identifica por un índice numérico que comienza en 0 y llega hasta longitud - 1.
Los arrays son una de las estructuras más fundamentales de cualquier lenguaje de programación. En Java, un array es un objeto: se crea en el heap, hereda de java.lang.Object y tiene la propiedad length. Esta naturaleza de objeto implica que las variables de array almacenan referencias, no los datos directamente.
ArrayList.Las características principales de los arrays en Java son:
✅ Tipado estricto: todos los elementos deben ser del mismo tipo (o subtipos compatibles).
✅ Tamaño fijo: se define al crearlo y no cambia.
✅ Indexación desde cero: el primer elemento es [0] y el último [length - 1].
✅ Acceso directo: acceder a cualquier posición es O(1), lo que hace a los arrays extremadamente eficientes para lectura.
✅ Inicialización automática: Java asigna valores por defecto a cada posición.
| Tipo del array | Valor por defecto | Ejemplo |
|---|---|---|
int[], long[], short[], byte[] |
0 |
int[] nums = new int[5]; // {0, 0, 0, 0, 0} |
double[], float[] |
0.0 |
double[] ds = new double[3]; // {0.0, 0.0, 0.0} |
boolean[] |
false |
boolean[] bs = new boolean[2]; // {false, false} |
char[] |
'\u0000' |
char[] cs = new char[3]; // {'\u0000', '\u0000', '\u0000'} |
String[], objetos |
null |
String[] ss = new String[4]; // {null, null, null, null} |
📝 Declaración e inicialización de arrays
En Java existen tres formas principales de declarar y crear un array. Es fundamental entender las diferencias entre declaración, creación e inicialización, ya que son pasos distintos que pueden realizarse juntos o por separado.
🔹 Forma 1: Declaración y creación con new
Se declara la variable y se reserva memoria para un número fijo de posiciones. Los elementos se inicializan con los valores por defecto del tipo.
// Declarar y crear un array de 5 enteros int[] numeros = new int[5]; // Equivalente (estilo C, menos idiomático en Java): int numeros2[] = new int[5]; // Arrays de otros tipos double[] precios = new double[100]; String[] nombres = new String[10]; boolean[] activos = new boolean[50];
int[] numeros sobre int numeros[]. La primera deja claro que el tipo es «array de int», mientras que la segunda es una herencia de C que puede generar confusión con declaraciones múltiples.🔹 Forma 2: Inicialización directa con llaves
Se declara, crea e inicializa el array en una sola sentencia. Java infiere el tamaño a partir del número de valores proporcionados.
// Array de 4 enteros con valores específicos int[] edades = {25, 30, 18, 42}; // Array de Strings String[] colores = {"rojo", "verde", "azul"}; // Array de doubles double[] notas = {8.5, 9.0, 7.3, 6.8, 10.0};
🔹 Forma 3: Creación anónima con new y valores
Útil cuando se necesita pasar un array como argumento a un método sin declarar una variable previa, o cuando se reasigna un array existente.
// Reasignar un array existente int[] datos; datos = new int[]{10, 20, 30}; // Pasar array como argumento procesarDatos(new int[]{1, 2, 3, 4}); // NOTA: esto NO compila // int[] x; x = {1, 2, 3}; ← Error: la forma con llaves solo funciona en la declaración
{1, 2, 3} fuera de la declaración genera un error de compilación. Fuera de la línea de declaración, debes usar new int[]{1, 2, 3}.🔑 Acceso a elementos y propiedad length
Cada elemento de un array se accede mediante su índice entre corchetes. El índice es un número entero que empieza en 0 (primer elemento) y llega hasta length - 1 (último elemento). La propiedad length (sin paréntesis, ya que no es un método) devuelve el número total de posiciones del array.
String[] ciudades = {"Madrid", "Barcelona", "Sevilla", "Valencia"}; // Leer elementos System.out.println(ciudades[0]); // Madrid (primer elemento) System.out.println(ciudades[3]); // Valencia (último elemento) // Modificar un elemento ciudades[1] = "Bilbao"; // Barcelona → Bilbao // Propiedad length System.out.println(ciudades.length); // 4 // Último elemento (patrón idiomático) String ultima = ciudades[ciudades.length - 1]; // Valencia
length es un campo público (atributo) del array, no un método. Por eso se escribe array.length sin paréntesis. Esto es diferente de String.length(), que sí es un método.🔄 Recorrido con bucle for clásico
El bucle for clásico es la forma más flexible de recorrer un array, ya que proporciona acceso directo al índice. Esto permite leer, modificar y conocer la posición exacta de cada elemento.
int[] temperaturas = {22, 28, 19, 31, 25, 17, 30}; // Recorrido completo for (int i = 0; i < temperaturas.length; i++) { System.out.println("Día " + (i + 1) + ": " + temperaturas[i] + "°C"); } // Buscar el máximo int max = temperaturas[0]; int posMax = 0; for (int i = 1; i < temperaturas.length; i++) { if (temperaturas[i] > max) { max = temperaturas[i]; posMax = i; } } System.out.println("Máxima: " + max + "°C el día " + (posMax + 1));
▶️ Recorrido inverso
Para recorrer un array desde el último elemento hasta el primero, se inicia el índice en length - 1 y se decrementa:
String[] palabras = {"Hola", "mundo", "Java"}; // Recorrido inverso for (int i = palabras.length - 1; i >= 0; i--) { System.out.println(palabras[i]); } // Salida: Java, mundo, Hola
🔁 Recorrido con for-each (enhanced for)
Desde Java 5, el bucle for-each simplifica la lectura de arrays cuando no necesitas el índice. La sintaxis es más limpia y menos propensa a errores de límites.
double[] precios = {19.99, 5.50, 12.75, 8.30, 45.00}; // Sintaxis: for (tipo variable : array) double total = 0; for (double precio : precios) { total += precio; } System.out.println("Total: " + total); // Total: 91.54 // Ejemplo con Strings String[] frutas = {"Manzana", "Plátano", "Naranja"}; for (String fruta : frutas) { System.out.println("Fruta: " + fruta); }
| Característica | Bucle for clásico |
Bucle for-each |
|---|---|---|
| Acceso al índice | Sí | No |
| Modificar elementos | Sí (array[i] = valor) |
No (la variable es una copia) |
| Recorrer en orden inverso | Sí | No |
| Legibilidad | Media | Alta |
| Riesgo de error de límites | Sí | No |
🧊 Arrays multidimensionales
Java permite crear arrays de múltiples dimensiones. Un array bidimensional es, en realidad, un array de arrays: cada posición del array principal contiene una referencia a otro array. Esto permite representar estructuras como matrices, tableros de juego o tablas de datos.
🔹 Declaración y creación de matrices
// Matriz 3×4 (3 filas, 4 columnas) int[][] matriz = new int[3][4]; // Inicialización directa int[][] notas = { {8, 7, 9}, // Alumno 0 {6, 8, 7}, // Alumno 1 {10, 9, 10}, // Alumno 2 {5, 6, 7} // Alumno 3 }; // Acceso: notas[fila][columna] System.out.println(notas[2][0]); // 10 (Alumno 2, asignatura 0)
🔹 Recorrido de una matriz con bucles anidados
int[][] notas = { {8, 7, 9}, {6, 8, 7}, {10, 9, 10}, {5, 6, 7} }; // Recorrido con for clásico for (int i = 0; i < notas.length; i++) { double suma = 0; for (int j = 0; j < notas[i].length; j++) { suma += notas[i][j]; } double media = suma / notas[i].length; System.out.printf("Alumno %d: media = %.1f%n", i, media); } // Recorrido con for-each for (int[] fila : notas) { for (int nota : fila) { System.out.print(nota + " "); } System.out.println(); }
🔹 Arrays irregulares (jagged arrays)
A diferencia de otros lenguajes, Java permite que cada fila de un array bidimensional tenga un tamaño diferente, creando lo que se conoce como un jagged array o array irregular:
// Array irregular: filas de diferente longitud int[][] triangulo = new int[4][]; // Solo se define la primera dimensión triangulo[0] = new int[]{1}; triangulo[1] = new int[]{1, 1}; triangulo[2] = new int[]{1, 2, 1}; triangulo[3] = new int[]{1, 3, 3, 1}; // Recorrer respetando el tamaño de cada fila for (int[] fila : triangulo) { for (int valor : fila) { System.out.print(valor + " "); } System.out.println(); } // Salida: // 1 // 1 1 // 1 2 1 // 1 3 3 1
🛠️ La clase java.util.Arrays
La clase utilitaria java.util.Arrays proporciona métodos estáticos muy útiles para trabajar con arrays: ordenación, búsqueda, comparación, relleno y conversión a String. Dominar estos métodos evita reinventar la rueda y produce código más limpio y eficiente.
import java.util.Arrays; public class MetodosArrays { public static void main(String[] args) { int[] numeros = {45, 12, 78, 3, 56, 23}; // 1. toString(): representación legible System.out.println(Arrays.toString(numeros)); // [45, 12, 78, 3, 56, 23] // 2. sort(): ordena en orden natural (ascendente) Arrays.sort(numeros); System.out.println(Arrays.toString(numeros)); // [3, 12, 23, 45, 56, 78] // 3. binarySearch(): busca en array ORDENADO int pos = Arrays.binarySearch(numeros, 45); System.out.println("45 está en posición: " + pos); // 45 está en posición: 3 // 4. fill(): rellena todas las posiciones int[] ceros = new int[5]; Arrays.fill(ceros, 99); System.out.println(Arrays.toString(ceros)); // [99, 99, 99, 99, 99] // 5. equals(): compara contenido (no referencia) int[] a = {1, 2, 3}; int[] b = {1, 2, 3}; System.out.println(a == b); // false (compara referencias) System.out.println(Arrays.equals(a, b)); // true (compara contenido) // 6. copyOf(): crea copia con nuevo tamaño int[] original = {10, 20, 30}; int[] copia = Arrays.copyOf(original, 5); System.out.println(Arrays.toString(copia)); // [10, 20, 30, 0, 0] } }
| Método | Descripción | Requisito previo |
|---|---|---|
Arrays.toString(arr) |
Representación legible del array | Ninguno |
Arrays.sort(arr) |
Ordena ascendentemente (in-place) | Ninguno |
Arrays.binarySearch(arr, key) |
Busca un valor y devuelve su índice | Array ordenado previamente |
Arrays.fill(arr, val) |
Rellena todas las posiciones con un valor | Ninguno |
Arrays.equals(a, b) |
Compara el contenido de dos arrays | Ninguno |
Arrays.copyOf(arr, len) |
Crea una copia con el tamaño indicado | Ninguno |
Arrays.deepToString(arr) |
toString para arrays multidimensionales | Ninguno |
Arrays.deepEquals(a, b) |
Compara arrays multidimensionales | Ninguno |
Arrays.sort(). Si el array no está ordenado, el resultado es indefinido y no se lanza ninguna excepción.📋 Copia de arrays
Copiar un array en Java no es tan simple como asignar una variable a otra. La asignación solo copia la referencia, no los datos. Existen tres técnicas principales para crear copias independientes.
import java.util.Arrays; public class CopiaArrays { public static void main(String[] args) { int[] original = {10, 20, 30, 40, 50}; // ❌ Esto NO copia: ambas variables apuntan al mismo array int[] alias = original; alias[0] = 999; System.out.println(original[0]); // 999 — ¡se modificó el original! // ✅ Método 1: System.arraycopy() — el más eficiente int[] copia1 = new int[original.length]; System.arraycopy(original, 0, copia1, 0, original.length); // ✅ Método 2: Arrays.copyOf() — copia con posible cambio de tamaño int[] copia2 = Arrays.copyOf(original, original.length); // ✅ Método 3: clone() — copia superficial int[] copia3 = original.clone(); // Las tres copias son independientes del original copia1[0] = 1; copia2[0] = 2; copia3[0] = 3; System.out.println(original[0]); // 999 — no afectado por las copias } }
🚫 Errores frecuentes con arrays
Los arrays son una fuente habitual de errores para programadores novatos (y no tan novatos). Conocer los errores más comunes permite evitarlos desde el principio.
❌ Error 1: Acceder a un índice fuera de rango
int[] nums = {10, 20, 30}; // ❌ Error: el índice 3 no existe (válidos: 0, 1, 2) System.out.println(nums[3]); // Lanza: ArrayIndexOutOfBoundsException // ❌ Error típico en bucle: usar <= en vez de < for (int i = 0; i <= nums.length; i++) { // ← debería ser < System.out.println(nums[i]); } // ✅ Correcto: usar estrictamente < for (int i = 0; i < nums.length; i++) { System.out.println(nums[i]); }
❌ Error 2: Confundir asignación de referencia con copia
int[] original = {1, 2, 3}; // ❌ Esto NO crea una copia independiente int[] copia = original; copia[0] = 99; System.out.println(original[0]); // 99 — ¡el original también cambió! // ✅ Para copiar, usa Arrays.copyOf() int[] copiaReal = Arrays.copyOf(original, original.length);
❌ Error 3: Comparar arrays con ==
int[] a = {1, 2, 3}; int[] b = {1, 2, 3}; // ❌ Compara referencias, no contenido System.out.println(a == b); // false // ✅ Compara contenido elemento a elemento System.out.println(Arrays.equals(a, b)); // true
❌ Error 4: Imprimir un array directamente con println
int[] datos = {5, 10, 15}; // ❌ Muestra la referencia, no el contenido System.out.println(datos); // Salida: [I@6d06d69c (hash del objeto) // ✅ Usa Arrays.toString() System.out.println(Arrays.toString(datos)); // Salida: [5, 10, 15]
🏪 Ejemplo integrador: gestión de inventario
Este programa completo combina todos los conceptos del artículo en un escenario realista: un sistema de gestión de inventario para una pequeña tienda que utiliza arrays paralelos para almacenar nombres de productos, precios y stock.
import java.util.Arrays; public class GestionInventario { // Arrays paralelos: misma posición = mismo producto static String[] nombres = {"Teclado", "Ratón", "Monitor", "Auriculares", "Webcam"}; static double[] precios = {45.99, 19.50, 289.00, 35.75, 62.30}; static int[] stock = {120, 200, 45, 80, 60}; public static void main(String[] args) { // 1. Mostrar inventario completo mostrarInventario(); // 2. Calcular valor total del inventario double valorTotal = calcularValorTotal(); System.out.printf("%nValor total del inventario: %.2f €%n", valorTotal); // 3. Buscar producto más caro int posCaro = buscarMasCaro(); System.out.printf("Producto más caro: %s (%.2f €)%n", nombres[posCaro], precios[posCaro]); // 4. Productos con stock bajo (< 50 unidades) System.out.println("\n⚠ Productos con stock bajo (< 50 uds):"); alertaStockBajo(50); // 5. Ordenar precios y mostrar ranking double[] preciosOrdenados = Arrays.copyOf(precios, precios.length); Arrays.sort(preciosOrdenados); System.out.println("\nPrecios ordenados: " + Arrays.toString(preciosOrdenados)); // 6. Generar informe de ventas simulado int[][] ventasMensuales = { {30, 25, 35}, // Teclado: ene, feb, mar {50, 45, 60}, // Ratón {10, 8, 12}, // Monitor {20, 22, 18}, // Auriculares {15, 12, 20} // Webcam }; informeVentas(ventasMensuales); } static void mostrarInventario() { System.out.println("╔══════════════════╦══════════╦═══════╗"); System.out.println("║ Producto ║ Precio ║ Stock ║"); System.out.println("╠══════════════════╬══════════╬═══════╣"); for (int i = 0; i < nombres.length; i++) { System.out.printf("║ %-16s ║ %7.2f€ ║ %3d ║%n", nombres[i], precios[i], stock[i]); } System.out.println("╚══════════════════╩══════════╩═══════╝"); } static double calcularValorTotal() { double total = 0; for (int i = 0; i < nombres.length; i++) { total += precios[i] * stock[i]; } return total; } static int buscarMasCaro() { int pos = 0; for (int i = 1; i < precios.length; i++) { if (precios[i] > precios[pos]) { pos = i; } } return pos; } static void alertaStockBajo(int umbral) { for (int i = 0; i < stock.length; i++) { if (stock[i] < umbral) { System.out.printf(" → %s: solo %d unidades%n", nombres[i], stock[i]); } } } static void informeVentas(int[][] ventas) { String[] meses = {"Enero", "Febrero", "Marzo"}; System.out.println("\n📊 Informe de ventas trimestrales:"); for (int i = 0; i < ventas.length; i++) { int totalProd = 0; for (int v : ventas[i]) { totalProd += v; } System.out.printf(" %s: %d uds vendidas (total trimestre)%n", nombres[i], totalProd); } } }
Este programa produce la siguiente salida:
╔══════════════════╦══════════╦═══════╗ ║ Producto ║ Precio ║ Stock ║ ╠══════════════════╬══════════╬═══════╣ ║ Teclado ║ 45.99€ ║ 120 ║ ║ Ratón ║ 19.50€ ║ 200 ║ ║ Monitor ║ 289.00€ ║ 45 ║ ║ Auriculares ║ 35.75€ ║ 80 ║ ║ Webcam ║ 62.30€ ║ 60 ║ ╚══════════════════╩══════════╩═══════╝ Valor total del inventario: 25136.80 € Producto más caro: Monitor (289.00 €) ⚠ Productos con stock bajo (< 50 uds): → Monitor: solo 45 unidades Precios ordenados: [19.5, 35.75, 45.99, 62.3, 289.0] 📊 Informe de ventas trimestrales: Teclado: 90 uds vendidas (total trimestre) Ratón: 155 uds vendidas (total trimestre) Monitor: 30 uds vendidas (total trimestre) Auriculares: 60 uds vendidas (total trimestre) Webcam: 47 uds vendidas (total trimestre)
✏️ Ejercicios prácticos
Ejercicio 1: ¿Qué imprime este código? (Comprensión)
Analiza el siguiente fragmento y determina la salida exacta sin ejecutarlo:
int[] a = {5, 10, 15, 20, 25}; int[] b = a; b[2] = 99; System.out.println(a[2]); System.out.println(a.length); System.out.println(a == b); int[] c = Arrays.copyOf(a, 3); System.out.println(Arrays.toString(c));
Ejercicio 2: Invertir un array (Aplicación)
Escribe un método invertir(int[] arr) que invierta el contenido del array in-place (sin crear otro array). Por ejemplo, {1, 2, 3, 4, 5} debe convertirse en {5, 4, 3, 2, 1}.
Ejercicio 3: Matriz de calificaciones (Diseño)
Diseña un programa que gestione las calificaciones de 5 alumnos en 3 asignaturas usando un array bidimensional. El programa debe:
a) Mostrar las notas de cada alumno.
b) Calcular la media de cada alumno.
c) Encontrar el alumno con la media más alta.
d) Contar cuántos alumnos tienen una media superior a 7.0.
❓ Preguntas frecuentes sobre Arrays en Java
Las dudas más comunes respondidas de forma clara y directa.
💬 Foro de discusión
¿Tienes dudas sobre Arrays en Java? Comparte tu pregunta con la comunidad.
Todavía no hay mensajes. ¡Sé el primero en participar!