SLIDE 1 / 5

1. Memoria Contigua: Por qué los Arrays inician en 0

Un array en Java almacena sus casillas pegadas una tras otra en memoria. El índice no es un "número de casilla ordinal", sino un desplazamiento (offset). Por eso acceder a un índice cualquiera toma exactamente el mismo tiempo: O(1).

base = 0x2000 [0] 10 0x2000 [1] 20 0x2004 [2] 30 0x2008 [3] 40 0x200C [4] 50 0x2010 [5] ¡FUERA! Cada int ocupa exactamente 4 bytes contiguos.
Calculadora de Salto de Memoria int[] numeros = new int[5];
Fórmula de Hardware: 0x2000 + 0 * 4 bytes
Dirección resultante: 0x2000
Valor guardado: 10

Al ser índice 0, el desplazamiento es 0 * 4 = 0 bytes. Por eso se lee instantáneamente el inicio del array.

2. Matrices en Java: Arrays de Arrays (Jagged)

En Java no existe una tabla rectangular continua en RAM. Una matriz int[][] es en realidad un array principal que contiene punteros a otros arrays independientes, cada uno con su propia longitud y ubicación en el Heap.

matriz[][] [0] ref [1] ref [2] ref [ 2 cols ] [ 5 columnas: irregular ] [ 3 cols ] Cada fila tiene su propio .length independiente.
Inspector de Filas Irregulares
Longitud (.length): 2
Elementos en memoria: [10, 20]
Dirección en Heap: @0x7a20 (Independiente)

La fila 0 tiene 2 casillas. Podés reasignarla con matriz[0] = new int[500]; sin alterar las demás filas.

3. Inmutabilidad de String: Grabado en Piedra

Un objeto String en Java NUNCA puede ser modificado. Métodos como .toUpperCase(), .trim() o .replace() no alteran el String original: instancian un NUEVO objeto en el Heap. Si no guardás la referencia, se pierde en el Garbage Collector.

Stack String s1 Heap: 0x4010 "hola" Heap: 0x4080 "HOLA" Estado tras ejecutar s1.toUpperCase(); s1 sigue valiendo "hola"
Simulador de Asignación
Valor actual de s1: "hola"
Objeto "HOLA" en Heap: Hué́rfano → Para el Garbage Collector

¡El error clásico del principiante! Llamar al método sin guardar el retorno deja a la variable apuntando al texto viejo.

4. El String Constant Pool: == vs .equals()

La JVM optimiza la memoria guardando los literales entre comillas en una piscina especial (String Pool). Si dos variables usan "java", apuntan al mismo objeto. Pero si usás new String("java"), forzás un objeto duplicado afuera. ¡Por eso JAMÁS se compara con ==!

Stack String a String b String c Heap String Constant Pool "java" @0x5010 new String "java" @0x7890
Verificador de Igualdad
Operación: a == b (Direcciones)
Resultado Booleano: true
Motivo JVM: Misma referencia en el String Pool (@0x5010)

Ambos literales reutilizan la misma celda de memoria. == compara punteros y devuelve true por casualidad.

5. StringBuilder: El Buffer Mutable de Texto

Concatenar texto en un bucle con + ("s += i") crea un nuevo String por cada vuelta, colapsando el Heap con miles de objetos basura. StringBuilder mantiene un único array interno de caracteres (char[]) que se expande dinámicamente.

String s += palabra; Heap saturado de basura N vueltas = N objetos huérfanos "a" → "ab" → "abc" → "abcd"... Complejidad O(N²) StringBuilder sb 1 Solo Objeto en Heap char[] mutable: [a|b|c|d|e|_|_] sb.append("..."); // in-situ Complejidad O(N)
Simulador de Carga: 1.000 Concatenaciones
Objetos instanciados en Heap: 1.000 objetos
Impacto en Garbage Collector: Crítico (999 objetos basura)
Tiempo estimado: ~120 ms (Lento)

Cada concatenación copia todos los caracteres anteriores a un nuevo array. Para 1.000 vueltas, el costo es exponencial.