SLIDE 1 / 5

1. Los Dos Niveles de Memoria en el Heap

En Java, un array de objetos NO guarda los objetos adentro de sus casillas. El array es un objeto contenedor en el Heap cuyas celdas contienen únicamente PUNTEROS a otras instancias repartidas en la memoria.

Stack plantel @0x1000 Heap: Array @0x1000 new Persona[3] [0] @0x5A00 → puntero [1] @0x5B00 → puntero [2] @0x5C00 → puntero Heap: Instancias Reales Persona @0x5A00 "Messi", Camiseta 10 Persona @0x5B00 "Di María", Camiseta 11 Persona @0x5C00 "Dibu", Camiseta 23
Explorador de Casillas
Acceso Stack: plantel -> Heap @0x1000
Casilla Array: plantel[0] = @0x5A00
Objeto Heap Destino: Persona("Messi", 10)
Persona[] plantel = new Persona[3];
plantel[0] = new Persona("Messi", 10);
plantel[1] = new Persona("Di María", 11);
plantel[2] = new Persona("Dibu", 23);

2. La Creación en Dos Pasos y la Trampa del null

Hacer new Persona[3] NO crea 3 personas. Crea un mueble con 3 cajones vacíos inicializados en null. Invocar un método sobre una casilla antes de instanciarla produce el temido NullPointerException.

Paso 1: Contenedor Únicamente Persona[] lista = new Persona[3]; [0] null ✕ [1] null [2] null ⚡ NullPointerException lista[0].getNombre(); ¡CRASH EN RUNTIME! lista[0] no tiene ningún objeto
Simulador de Inicialización
Estado en Casilla [0]: null (Vacío)
Resultado Invocación: NullPointerException
// PASO 1: Contenedor (3 casillas en null)
Persona[] lista = new Persona[3];

// PASO 2: Instanciar cada elemento
lista[0] = new Persona("Lautaro", 22);
System.out.println(lista[0].getNombre()); // OK!

3. Recorrer con Seguridad: El Filtro Contra Nulos

En la práctica real los arrays raramente están llenos al 100%. Todo bucle for o for-each debe incluir una compuerta de seguridad `if (elem != null)` para procesar únicamente elementos vivos y descartar casillas vacías.

[0] "Ana" [1] "Leo" [2] null [3] "Dibu" [4] null i = 0 if (p != null) -> true ✓ p.presentarse() ejecutado correctamente
Simulador de Bucle
Índice actual: i = 0
Valor en plantel[i]: Persona("Ana")
Compuerta de Guarda: true (Pasa)
for (Persona p : plantel) {
  if (p != null) { // <-- Blindaje obligatorio
    p.presentarse();
  }
}

4. Capacidad Física vs Cantidad Lógica

Un array reservado de tamaño 6 puede tener solo 3 elementos activos. Una variable contadora `cantidad` rastrea el próximo índice libre. Cuando se llena (`cantidad == capacidad`), se redimensiona copiando a un nuevo array más grande.

Memoria del Array (Capacidad = 6) Activos: 3/6 [0] Ana [1] Leo [2] Dibu [3] null [4] null [5] null Insertar en posición libre: plantel[cantidad] plantel[3] = nuevo; cantidad++; // cantidad pasa a 4 No se recorre todo el arreglo; la inserción es O(1).
Operaciones de Lista Parcial
Capacidad Física: plantel.length = 6
Cantidad Lógica: cantidad = 3
Espacio Disponible: 3 casillas libres
public void agregar(Persona p) {
  if (cantidad == plantel.length) {
    plantel = Arrays.copyOf(plantel, plantel.length * 2);
  }
  plantel[cantidad] = p;
  cantidad++;
}

5. Ordenar Arrays de Objetos: Escribir el Criterio a Mano

Arrays.sort() ordena solo un array de primitivos. Con objetos no sabe qué comparar: hay que escribir el bucle de comparación a mano, campo por campo. El ordenamiento intercambia punteros en el array sin duplicar objetos en el Heap — vas a automatizar este criterio en la lección 16.

Array plantel: Intercambio de Referencias [0] "Di María" Camiseta: #11 [1] "Dibu" Camiseta: #23 [2] "Messi" Camiseta: #10 Estado Inicial: Desordenado por camiseta [11, 23, 10] // Arrays.sort(plantel) revienta: ClassCastException Los objetos en el Heap nunca se mueven ni se copian; solo cambian los punteros en las casillas.
Estrategias de Orden
Criterio Activo: Orden de inserción original
Comparación Activa: plantel
// Ascendente: buscás el menor y lo llevás al frente
if (plantel[j].getCamiseta() < plantel[menor].getCamiseta()) {
  menor = j;
}

// Descendente: mismo bucle, comparación invertida
if (plantel[j].getCamiseta() > plantel[mayor].getCamiseta()) {
  mayor = j;
}