Arrays y Manejo de Strings en Java
Hasta acá guardaste datos en variables sueltas: una edad, un nombre, un precio. Eso alcanza mientras sepas de antemano cuántos valores vas a manejar. Pero apenas necesitás las notas de un curso, los píxeles de una imagen o las palabras de un texto, declarar nota1, nota2, nota3… deja de ser una opción.
El array es la primera estructura de datos del lenguaje: un contenedor de tamaño fijo que guarda muchos valores del mismo tipo bajo un único nombre. Y el String —que parece un tipo más— es en realidad un objeto construido sobre un array de caracteres, con una regla propia que cambia todo: es inmutable.
Esta lección cubre las dos cosas juntas porque comparten el mismo trasfondo: cómo Java acomoda los datos en memoria. Entender eso es lo que después explica por qué == falla al comparar textos, por qué concatenar dentro de un bucle es lento, y por qué un array no puede crecer.

1. Por qué existe el array: memoria contigua y acceso constante
Un array es un bloque de memoria contiguo —un solo tramo, sin huecos— dividido en casillas del mismo tamaño. Esa decisión de diseño explica prácticamente todo lo demás.
Tres consecuencias que conviene tener claras desde el principio:
- El índice arranca en 0 porque no cuenta posiciones, mide desplazamiento.
edades[0]está a cero casillas del inicio. Por eso el último índice válido siempre eslength - 1. - El acceso es instantáneo —lo que en análisis de algoritmos se escribe O(1)—. No hay búsqueda: hay una cuenta aritmética. Es la propiedad que hace del array la base de casi todas las demás estructuras.
- El tamaño no puede cambiar. Justo después del bloque hay otra cosa en memoria. Para “agrandar” un array hay que pedir un bloque nuevo y copiar; lo vemos en la sección 4.
lengthes un atributo, no un método: se escribearray.lengthsin paréntesis. EnString, en cambio, es un método:texto.length(). Es una de las inconsistencias históricas de Java y una fuente clásica de errores de compilación.
2. Declarar, instanciar e inicializar
Estas tres cosas son distintas y conviene no confundirlas: declarar crea la variable, instanciar reserva el bloque en el Heap, inicializar pone los valores.
// Forma 1: declarar e instanciar vacío (Java llena con valores por defecto)
int[] edades = new int[5];
// Forma 2: literal de inicialización (el tamaño lo deduce el compilador)
String[] lenguajes = {"Java", "Python", "TypeScript", "Go"};
// Forma 3: instanciación anónima (útil para pasar un array a un método)
imprimir(new int[]{10, 20, 30});
// Declarar ahora, instanciar después
double[] precios; // precios vale null: no hay bloque todavía
precios = new double[3]; // ahora sí existe el bloque
La sintaxis int edades[] también compila —viene heredada de C— pero no la uses. int[] edades dice lo correcto: el tipo de la variable es array de int, no int.
Valores por defecto al instanciar con new
Java nunca deja memoria con basura: al reservar el bloque lo pone en cero binario, que cada tipo interpreta a su manera.
| Tipo | Valor por defecto |
|---|---|
byte, short, int, long | 0 |
float, double | 0.0 |
char | '\u0000' (el carácter nulo) |
boolean | false |
Cualquier referencia (String, objetos, arrays) | null |
Esto tiene una consecuencia práctica importante: new String[3] no te da tres cadenas vacías, te da tres null. Recorrerlo y llamar a .length() sin verificar termina en NullPointerException.
Los dos errores que vas a ver seguro
int[] datos = new int[3];
datos[3] = 99; // ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
datos[-1] = 99; // ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 3
int n = -5;
int[] otro = new int[n]; // NegativeArraySizeException: -5
Los tres son errores de ejecución, no de compilación: el compilador no sabe qué valor va a tener el índice. Java verifica el rango en cada acceso —a diferencia de C, donde escribir fuera del array corrompe memoria en silencio—. Es un costo pequeño a cambio de que el error aparezca exactamente donde se produjo.
3. Recorrer un array
String[] frutas = {"Manzana", "Banana", "Naranja", "Frutilla"};
// A) for clásico: tenés el índice, podés modificar el array
for (int i = 0; i < frutas.length; i++) {
System.out.println("Índice " + i + ": " + frutas[i]);
}
// B) for-each: más limpio cuando el índice no importa
for (String fruta : frutas) {
System.out.println("Fruta: " + fruta);
}
// C) hacia atrás
for (int i = frutas.length - 1; i >= 0; i--) {
System.out.println(frutas[i]);
}
Cuándo usar cada uno. El for-each es la opción por defecto: se lee mejor y elimina de raíz los errores de índice. Pero tiene un límite que sorprende a mucha gente:
int[] numeros = {1, 2, 3};
for (int n : numeros) {
n = n * 2; // NO modifica el array: n es una copia del valor
}
System.out.println(Arrays.toString(numeros)); // [1, 2, 3]
for (int i = 0; i < numeros.length; i++) {
numeros[i] = numeros[i] * 2; // esto SÍ lo modifica
}
System.out.println(Arrays.toString(numeros)); // [2, 4, 6]
La variable del for-each es una copia de cada elemento, no la casilla en sí. Regla simple: si tenés que escribir en el array, necesitás el índice; si solo tenés que leerlo, usá for-each.
4. El tamaño es fijo: qué hacer cuando el array se llena
No existe array.add(...). Un array de 4 posiciones muere con 4 posiciones. Cuando necesitás más, la única salida es pedir un bloque nuevo y copiar el contenido.
ArrayList, que vas a ver en la lección de colecciones.import java.util.Arrays;
int[] datos = {10, 20, 30, 40};
// Opción 1: Arrays.copyOf — la más legible
int[] masGrande = Arrays.copyOf(datos, 8); // [10, 20, 30, 40, 0, 0, 0, 0]
// Opción 2: un rango concreto (el índice final NO se incluye)
int[] medio = Arrays.copyOfRange(datos, 1, 3); // [20, 30]
// Opción 3: System.arraycopy — control total sobre origen y destino
int[] destino = new int[8];
System.arraycopy(datos, 0, destino, 0, datos.length);
// origen, desde, destino, hacia, cuántos
Este trabajo manual es exactamente el que ArrayList te ahorra. Pero conviene haberlo hecho a mano una vez: es la única forma de entender por qué agregar elementos a una lista a veces es instantáneo y a veces no.
5. Arrays de primitivos vs. arrays de objetos
La diferencia importa mucho más de lo que parece.
int[] numeros = new int[3]; // 3 casillas con el valor 0
String[] nombres = new String[3]; // 3 casillas con la referencia null
System.out.println(numeros[0]); // 0
System.out.println(nombres[0]); // null
System.out.println(nombres[0].length()); // NullPointerException
Un array de primitivos contiene los valores. Un array de objetos contiene referencias: los objetos viven en otra parte del Heap y el array solo guarda las direcciones. Eso explica el comportamiento de las copias:
StringBuilder[] original = { new StringBuilder("Hola") };
StringBuilder[] copia = Arrays.copyOf(original, 1);
copia[0].append(" mundo");
System.out.println(original[0]); // "Hola mundo" ← ¡también cambió!
System.out.println(original[0] == copia[0]); // true
Arrays.copyOf hace una copia superficial (shallow copy): duplica el array de referencias, no los objetos apuntados. Los dos arrays son distintos, pero apuntan a los mismos objetos. Si necesitás independencia real —una copia profunda— tenés que clonar cada elemento vos mismo.
Con String este problema no aparece nunca, y la razón es la sección 8: los String son inmutables, así que compartir la referencia no puede hacer daño.
Los arrays de objetos tienen bastante más tela que cortar —casillas en
null, ordenamiento conComparator, capacidad contra cantidad—, pero necesitan clases y constructores. Por eso tienen lección propia: Arrays de Objetos, la número 9, justo después de encapsulamiento.
6. Matrices y arrays irregulares
En Java no existen las matrices como tipo propio. Lo que existe es un array cuyos elementos son, a su vez, arrays.
int[][] es un array de referencias. Las filas viven separadas en el Heap, así que nada obliga a que midan lo mismo: eso es un jagged array.// Matriz rectangular: 3 filas x 3 columnas
int[][] tablero = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Recorrido con bucles anidados
for (int fila = 0; fila < tablero.length; fila++) {
for (int col = 0; col < tablero[fila].length; col++) { // ← length de ESA fila
System.out.print(tablero[fila][col] + " ");
}
System.out.println();
}
// Recorrido con for-each anidado (cuando no necesitás los índices)
for (int[] fila : tablero) {
for (int valor : fila) {
System.out.print(valor + " ");
}
System.out.println();
}
Array irregular (jagged), cuando cada fila tiene un tamaño propio:
int[][] datos = new int[3][]; // solo el array externo; las filas quedan en null
datos[0] = new int[]{1, 2, 3};
datos[1] = new int[]{4, 5, 6, 7, 8};
datos[2] = new int[]{9, 0};
System.out.println(datos[1].length); // 5
Escribir tablero[fila].length en vez de tablero[0].length no es un detalle estético: es lo que hace que el mismo bucle funcione con matrices rectangulares e irregulares.
Para imprimir una matriz completa,
Arrays.toString()no alcanza: te muestra las direcciones de memoria de las filas. UsáArrays.deepToString(tablero).
7. java.util.Arrays: el cinturón de herramientas
Casi nada de lo que necesitás hacer con un array hace falta escribirlo a mano. java.util.Arrays ya lo tiene.
| Método | Qué hace |
|---|---|
Arrays.toString(a) | Representación legible de un array de una dimensión |
Arrays.deepToString(m) | Lo mismo para matrices y arrays anidados |
Arrays.sort(a) | Ordena modificando el array original (in-place) |
Arrays.sort(a, desde, hasta) | Ordena solo un rango |
Arrays.binarySearch(a, v) | Búsqueda binaria — exige el array ya ordenado |
Arrays.copyOf(a, n) | Copia redimensionada |
Arrays.copyOfRange(a, d, h) | Copia de un rango, h excluido |
Arrays.fill(a, v) | Rellena todas las casillas con un valor |
Arrays.equals(a, b) | Compara contenido de arrays de una dimensión |
Arrays.deepEquals(m, n) | Compara contenido de arrays anidados |
Arrays.stream(a) | Convierte el array en un stream para sumar, filtrar, promediar |
import java.util.Arrays;
public class EjemploArrays {
public static void main(String[] args) {
int[] numeros = {42, 12, 89, 7, 23};
System.out.println("Original: " + Arrays.toString(numeros));
Arrays.sort(numeros); // ordena el array original
System.out.println("Ordenado: " + Arrays.toString(numeros)); // [7, 12, 23, 42, 89]
int indice = Arrays.binarySearch(numeros, 23);
System.out.println("Índice de 23: " + indice); // 2
int[] copia = Arrays.copyOf(numeros, 3);
System.out.println("Copia: " + Arrays.toString(copia)); // [7, 12, 23]
int[] ceros = new int[5];
Arrays.fill(ceros, -1);
System.out.println(Arrays.toString(ceros)); // [-1, -1, -1, -1, -1]
// Estadísticas sin escribir un solo bucle
System.out.println("Suma: " + Arrays.stream(numeros).sum());
System.out.println("Máximo: " + Arrays.stream(numeros).max().getAsInt());
System.out.println("Promedio: " + Arrays.stream(numeros).average().getAsDouble());
}
}
Dos trampas que hay que conocer
1. == tampoco sirve para comparar arrays. Compara referencias, igual que con los objetos:
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b); // false — son dos bloques distintos
System.out.println(a.equals(b)); // false — un array no sobrescribe equals
System.out.println(Arrays.equals(a, b)); // true — esta es la correcta
2. binarySearch sobre un array desordenado devuelve basura silenciosamente. No lanza excepción, no avisa: simplemente retorna un número sin sentido, porque el algoritmo asume que el array está ordenado. Ordená siempre antes de buscar.
8. Strings: por qué son inmutables
Un String es un objeto que envuelve una secuencia de caracteres. Su regla central es que una vez creado, su contenido no cambia jamás. Ningún método de String modifica la cadena original: todos devuelven una cadena nueva.
= reasigna la variable. El objeto original queda intacto y, si nadie más lo apunta, se convierte en basura.String texto = "hola";
texto.toUpperCase(); // devuelve "HOLA", pero se descarta
System.out.println(texto); // "hola" — no cambió nada
String mayus = texto.toUpperCase(); // así sí: guardás el resultado
System.out.println(mayus); // "HOLA"
Olvidar la asignación es el error número uno con String. Como el método no falla ni avisa, el programa sigue corriendo con el valor viejo.
¿Por qué Java tomó esta decisión? No es un capricho:
- Seguridad. Rutas de archivo, URLs y credenciales viajan como
String. Si fueran mutables, un método al que le pasaste una ruta ya validada podría cambiarla después de la validación. - Concurrencia. Un objeto que no cambia se puede compartir entre hilos sin ningún tipo de sincronización.
- Rendimiento del hashing.
Stringcalcula suhashCode()una sola vez y lo cachea. Es lo que hace que usar cadenas como clave de unHashMapsea rápido. - Reutilización. Como nadie puede modificarlos, la JVM puede compartir un mismo objeto entre muchas variables. Eso es el pool.
9. El String Constant Pool y la trampa de ==
Para no duplicar cadenas idénticas, la JVM mantiene una zona especial dentro del Heap llamada String Constant Pool. Cuando escribís un literal entre comillas, la JVM busca primero en el pool y reutiliza el objeto si ya está.
== a veces "parece funcionar" con cadenas. Funciona por casualidad, y deja de hacerlo apenas la cadena se arma en tiempo de ejecución.String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");
System.out.println(s1 == s2); // true — misma referencia del pool
System.out.println(s1 == s3); // false — new siempre crea un objeto aparte
System.out.println(s1.equals(s3)); // true — compara el contenido
Y el caso que convence a cualquiera de no usar nunca ==:
String a = "Java";
String b = "Ja" + "va"; // el compilador lo resuelve: va al pool
System.out.println(a == b); // true
String parte = "Ja";
String c = parte + "va"; // se arma en ejecución: objeto nuevo
System.out.println(a == c); // false ← mismo texto, otro objeto
System.out.println(a.equals(c)); // true
Regla de oro: para comparar el contenido de dos cadenas usá siempre
.equals()o.equalsIgnoreCase().==compara identidad de objetos y va a traicionarte apenas la cadena venga de un archivo, de la consola o de una concatenación.
Truco defensivo contra NullPointerException: si uno de los dos lados puede ser null, poné el literal a la izquierda.
String entrada = null;
entrada.equals("salir"); // NullPointerException
"salir".equals(entrada); // false — seguro
10. Recorrer y cortar texto: todo es cuestión de índices
Un String se indexa igual que un array, desde 0 hasta length() - 1.
substring, copyOfRange, subList y los Stream.Métodos esenciales de String
| Método | Devuelve |
|---|---|
length() | Cantidad de caracteres |
charAt(i) | El carácter en la posición i |
substring(d, h) | El fragmento de d a h - 1 |
indexOf(s) / lastIndexOf(s) | Primera / última posición de s, o -1 si no está |
contains(s) | true si s aparece en la cadena |
startsWith(s) / endsWith(s) | true si empieza / termina con s |
toUpperCase() / toLowerCase() | Una copia en mayúsculas / minúsculas |
trim() / strip() | Una copia sin espacios en los extremos |
isEmpty() / isBlank() | Si mide 0 / si solo tiene espacios |
replace(a, b) | Una copia con a reemplazado por b |
split(regex) | Un String[] partido por el separador |
String.join(sep, partes) | Une varias cadenas con un separador |
repeat(n) | La cadena repetida n veces |
toCharArray() | Un char[] con los caracteres |
String texto = " Aprendiendo Java en 2026 ";
System.out.println(texto.length()); // 28
System.out.println(texto.trim()); // "Aprendiendo Java en 2026"
System.out.println(texto.toUpperCase()); // " APRENDIENDO JAVA EN 2026 "
System.out.println(texto.contains("Java")); // true
System.out.println(texto.indexOf("Java")); // 14
System.out.println(texto.substring(14, 18)); // "Java"
System.out.println(texto.replace("2026", "2027"));
// Partir y volver a unir
String csv = "Buenos Aires,Neuquén,Córdoba,Salta";
String[] provincias = csv.split(",");
System.out.println(provincias.length); // 4
System.out.println(String.join(" | ", provincias));
// Recorrer carácter por carácter
String palabra = "Java";
for (int i = 0; i < palabra.length(); i++) {
System.out.println(i + ": " + palabra.charAt(i));
}
for (char c : palabra.toCharArray()) {
System.out.println(c);
}
trim() vs strip(), isEmpty() vs isBlank()
String s = " ";
System.out.println(s.isEmpty()); // false — tiene 6 caracteres
System.out.println(s.isBlank()); // true — todos son espacios en blanco
strip() (Java 11+) es la versión moderna de trim(): entiende el rango completo de espacios Unicode, mientras que trim() solo elimina caracteres por debajo de U+0020. En código nuevo, usá strip() e isBlank().
Formatear e interpolar
String nombre = "Laura";
double promedio = 8.457;
// Concatenación simple
System.out.println("Alumna: " + nombre + " — promedio " + promedio);
// formatted / String.format: control sobre decimales y ancho
System.out.println("Alumna: %s — promedio %.2f".formatted(nombre, promedio));
// Alumna: Laura — promedio 8,46
// Bloques de texto (Java 15+): saltos de línea sin escapes
String json = """
{
"nombre": "Laura",
"promedio": 8.46
}
""";
11. StringBuilder: cuándo la inmutabilidad se vuelve cara
La inmutabilidad tiene un precio, y se paga dentro de los bucles. Cada += sobre un String crea un objeto nuevo y copia todo lo acumulado hasta ese momento.
StringBuilder escribe en un buffer y solo copia cuando se le agota la capacidad.// INEFICIENTE: 1000 objetos temporales y medio millón de caracteres copiados
String resultado = "";
for (int i = 0; i < 1000; i++) {
resultado += i + ", ";
}
// EFICIENTE: un único buffer mutable
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i).append(", ");
}
String resultadoEficiente = sb.toString();
La API de StringBuilder
StringBuilder sb = new StringBuilder("Hola");
sb.append(" mundo"); // "Hola mundo"
sb.insert(0, ">> "); // ">> Hola mundo"
sb.replace(0, 3, "-- "); // "-- Hola mundo"
sb.deleteCharAt(0); // "- Hola mundo"
sb.reverse(); // "odnum aloH -"
System.out.println(sb.length());
System.out.println(sb.toString()); // convertir a String al final
// Encadenamiento: cada método devuelve el mismo StringBuilder
String frase = new StringBuilder()
.append("Java")
.append(" ")
.append(2026)
.toString();
Si sabés más o menos cuánto texto vas a acumular, reservá la capacidad de entrada y te ahorrás todos los redimensionamientos: new StringBuilder(4096).
Cuándo NO hace falta StringBuilder
El compilador ya optimiza la concatenación dentro de una sola expresión. Esto está perfecto así:
String mensaje = "Hola " + nombre + ", tenés " + cantidad + " mensajes";
El problema aparece únicamente cuando la concatenación ocurre repetida a lo largo de varias iteraciones, porque ahí el compilador no puede fusionarlas: cada vuelta es una expresión distinta.
StringBuilder vs StringBuffer
Son la misma clase con la misma API. StringBuffer es la versión antigua y sincronizada: cada método es seguro entre hilos, y por eso es más lenta. Usá StringBuilder salvo que varios hilos vayan a escribir en el mismo buffer, cosa que casi nunca pasa.
12. Errores frecuentes
- Confundir
lengthconlength().array.lengthes un atributo;texto.length()es un método. - Comparar cadenas con
==. Funciona con literales y falla con todo lo demás. Usá.equals(). - Olvidar asignar el resultado.
texto.trim();no hace nada;texto = texto.trim();sí. - Iterar hasta
<= length. El último índice válido eslength - 1. - Usar
binarySearchsin ordenar. No falla: devuelve un resultado incorrecto en silencio. - Esperar que
Arrays.copyOfclone los objetos. Copia referencias, no objetos. - Imprimir una matriz con
toString. Para arrays anidados vadeepToString. - Recorrer un
String[]recién creado connew. Todas sus casillas sonnullhasta que las llenes. - Concatenar dentro de un bucle largo. Ahí
StringBuilderno es una preferencia, es una necesidad.
13. Ejercicios prácticos guiados
Ejercicio 1 — Verificador de palíndromos
Escribí un programa que reciba una cadena, ignore espacios y mayúsculas, y determine si se lee igual en los dos sentidos.
Ver solución sugerida
public class VerificadorPalindromo {
public static boolean esPalindromo(String texto) {
if (texto == null) return false;
// 1. Normalizar: sin espacios, todo en minúsculas
String limpio = texto.replaceAll("\\s+", "").toLowerCase();
// 2. Comparar desde los dos extremos hacia el centro
int izq = 0;
int der = limpio.length() - 1;
while (izq < der) {
if (limpio.charAt(izq) != limpio.charAt(der)) {
return false;
}
izq++;
der--;
}
return true;
}
public static void main(String[] args) {
System.out.println(esPalindromo("Neuquen")); // true
System.out.println(esPalindromo("Anita lava la tina")); // true
System.out.println(esPalindromo("Java")); // false
}
}
La versión corta usa StringBuilder:
String limpio = texto.replaceAll("\\s+", "").toLowerCase();
String invertido = new StringBuilder(limpio).reverse().toString();
boolean esPalindromo = limpio.equals(invertido);
Las dos son correctas, pero no cuestan lo mismo: la de los dos punteros no crea ninguna cadena nueva y corta apenas encuentra la primera diferencia; la de StringBuilder siempre recorre e invierte el texto completo. Con cadenas cortas da igual; con textos grandes, no.
Ejercicio 2 — Estadísticas de un array
Dado un int[], calculá el mínimo, el máximo y el promedio en un solo recorrido, sin usar Arrays.sort.
Ver solución sugerida
public class Estadisticas {
public static void main(String[] args) {
int[] temperaturas = {18, 25, 12, 31, 22, 9, 27};
if (temperaturas.length == 0) {
System.out.println("El array está vacío");
return;
}
// Arrancar con el primer elemento, nunca con 0:
// si todos los valores fueran negativos, el máximo daría 0 y sería falso.
int min = temperaturas[0];
int max = temperaturas[0];
long suma = 0;
for (int t : temperaturas) {
if (t < min) min = t;
if (t > max) max = t;
suma += t;
}
double promedio = (double) suma / temperaturas.length;
System.out.println("Mínima: " + min); // 9
System.out.println("Máxima: " + max); // 31
System.out.println("Promedio: %.2f".formatted(promedio)); // 20,57
}
}
Dos detalles que importan: inicializar min y max con temperaturas[0] en lugar de 0, y el (double) antes de dividir —sin él, suma / length sería una división entera y perderías los decimales.
Ejercicio 3 — Contar palabras y encontrar la más larga
Dado un texto, mostrá cuántas palabras tiene y cuál es la más larga.
Ver solución sugerida
public class AnalizadorTexto {
public static void main(String[] args) {
String texto = " Java es un lenguaje compilado e interpretado ";
// strip() saca los espacios de los extremos;
// \\s+ parte por uno o más espacios, así los espacios dobles no generan
// palabras vacías.
String[] palabras = texto.strip().split("\\s+");
String masLarga = "";
for (String palabra : palabras) {
if (palabra.length() > masLarga.length()) {
masLarga = palabra;
}
}
System.out.println("Palabras: " + palabras.length); // 7
System.out.println("Más larga: " + masLarga); // interpretado
// Reconstruir el texto normalizado
System.out.println(String.join(" ", palabras));
}
}
Si partieras con split(" ") en lugar de split("\\s+"), los espacios dobles producirían cadenas vacías y el conteo daría mal. Es el motivo por el que casi siempre conviene partir por la expresión regular.
Ejercicio 4 — Transponer una matriz
Escribí un método que reciba una matriz rectangular de int y devuelva su transpuesta (filas por columnas).
Ver solución sugerida
import java.util.Arrays;
public class Transponer {
public static int[][] transponer(int[][] m) {
int filas = m.length;
int columnas = m[0].length;
// La transpuesta invierte las dimensiones
int[][] t = new int[columnas][filas];
for (int i = 0; i < filas; i++) {
for (int j = 0; j < columnas; j++) {
t[j][i] = m[i][j];
}
}
return t;
}
public static void main(String[] args) {
int[][] original = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println(Arrays.deepToString(original));
// [[1, 2, 3], [4, 5, 6]]
System.out.println(Arrays.deepToString(transponer(original)));
// [[1, 4], [2, 5], [3, 6]]
}
}
Fijate que el array de salida se declara new int[columnas][filas], no new int[filas][columnas]: es el error más común de este ejercicio y se manifiesta como un ArrayIndexOutOfBoundsException apenas la matriz no es cuadrada.
Para llevarte
- El array guarda sus elementos en un bloque contiguo: de ahí salen el índice desde 0, el acceso instantáneo y el tamaño fijo.
array.lengthes atributo;texto.length()es método. El último índice válido siempre eslength - 1.- Un array no crece: crecer es crear uno nuevo y copiar. Eso es exactamente lo que
ArrayListautomatiza. - Los arrays de objetos guardan referencias:
Arrays.copyOfhace copia superficial, no profunda. - Una matriz es un array de arrays. Sus filas son objetos independientes y pueden medir distinto.
Arraysya resuelve ordenar, buscar, copiar, rellenar y comparar.binarySearchexige ordenar primero.Stringes inmutable: ningún método lo modifica, todos devuelven una cadena nueva que hay que asignar.- El String Constant Pool hace que
==a veces parezca funcionar. El contenido se compara con.equals(), siempre. StringBuilderes obligatorio cuando concatenás dentro de un bucle; en una sola expresión el compilador ya lo resuelve por vos.