Arrays de n-dimensiones
Java permite crear arrays con cualquier número de dimensiones. La idea que hemos visto con 2D y 3D se puede generalizar para 4, 5 o más dimensiones. En la práctica, esto se usa en contextos muy específicos (simulaciones científicas, cálculos tensoriales, aprendizaje automático, etc.), pero es importante comprenderlo como generalización del concepto.
Un array de N dimensiones es, en esencia, un array cuyos elementos son arrays de (N-1) dimensiones.
Patrón general
| Dimensiones | Ejemplo visual | Índices necesarios |
|---|---|---|
| 1D | Lista | [i] |
| 2D | Tabla | [i][j] |
| 3D | Conjunto de tablas | [i][j][k] |
| 4D | Secuencia de cubos | [i][j][k][l] |
| ND | Estructura abstracta | [i₁][i₂][i₃]...[iₙ] |
Declaración
Para N dimensiones, simplemente se añaden N pares de corchetes []:
// Sintaxis general
tipoDato[][][]...[] nombreArray; // N pares de []
// Ejemplos
int[][][][] tensor4D;
double[][][][][] datos5D;
Creación (inicialización)
Con new
// Array 4D: 2 × 3 × 4 × 5
int[][][][] tensor = new int[2][3][4][5];
// Todos los valores se inicializan a 0
Cuando se crea una array con new, todas las posiciones toman el valor por defecto del tipo de dato del array.
Con valores literales (para pocas dimensiones)
int[][][][] tensor = {
{ // dimensión 0, índice 0
{{1, 2}, {3, 4}},
{{5, 6}, {7, 8}}
},
{ // dimensión 0, índice 1
{{9, 10}, {11, 12}},
{{13, 14}, {15, 16}}
}
};
A partir de 4 dimensiones, los literales anidados se vuelven difíciles de leer. Es preferible inicializar con new y rellenar mediante bucles.
Acceso a elementos
int[][][][] tensor = new int[2][3][4][5];
// Asignar un valor
tensor[1][2][3][4] = 42;
// Leer un valor
System.out.println(tensor[1][2][3][4]); // 42
Recorrido con N bucles anidados
Para recorrer un array de N dimensiones se necesitan N bucles for anidados. El patrón es siempre el mismo:
Ejemplo: array 4D
int[][][][] tensor = new int[2][3][4][5];
// Rellenar
int val = 0;
for (int i = 0; i < tensor.length; i++) {
for (int j = 0; j < tensor[i].length; j++) {
for (int k = 0; k < tensor[i][j].length; k++) {
for (int l = 0; l < tensor[i][j][k].length; l++) {
tensor[i][j][k][l] = val++;
}
}
}
}
// Leer un valor concreto
System.out.println(tensor[0][1][2][3]); // algún valor
Recorrido genérico con Arrays.deepToString
Para visualizar un array multidimensional de forma rápida (sin escribir múltiples bucles), Java ofrece Arrays.deepToString():
import java.util.Arrays;
int[][][][] tensor = {
{ {{1, 2}, {3, 4}}, {{5, 6}, {7, 8}} },
{ {{9, 10}, {11, 12}}, {{13, 14}, {15, 16}} }
};
System.out.println(Arrays.deepToString(tensor));
// [[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]]
Arrays.toString() solo funciona para arrays 1D. Para más dimensiones, siempre usa Arrays.deepToString().
Tamaño de cada dimensión
int[][][][] tensor = new int[2][3][4][5];
int dim0 = tensor.length; // 2
int dim1 = tensor[0].length; // 3
int dim2 = tensor[0][0].length; // 4
int dim3 = tensor[0][0][0].length; // 5
En general, para la dimensión d (empezando desde 0):
tensor[0][0]...[0].length // con d ceros como índices
Total de elementos
El número total de elementos en un array de N dimensiones con tamaños d₁ × d₂ × ... × dₙ es simplemente el producto de todos los tamaños:
total = d₁ × d₂ × d₃ × ... × dₙ
Por ejemplo, new int[2][3][4][5] contiene 2 × 3 × 4 × 5 = 120 elementos.
Cuándo usar arrays de alta dimensionalidad
Aunque Java permite cualquier número de dimensiones, en la práctica:
- 1D y 2D → Uso muy frecuente (listas, tablas, matrices).
- 3D → Uso moderado (imágenes en color, datos volumétricos).
- 4D o más → Uso poco frecuente y especializado. Para estas situaciones suelen ser preferibles alternativas como:
- Colecciones anidadas (
List<List<...>>) para tamaños variables. - Clases y objetos que encapsulen la estructura.
- Librerías especializadas (como ND4J para cálculo tensorial en Java).
- Colecciones anidadas (
Ejemplo completo
import java.util.Arrays;
public class Tensor4D {
public static void main(String[] args) {
// Representar datos con 4 dimensiones: tiempo × profundidad × fila × columna
int[][][][] datos = new int[2][2][2][2];
// Rellenar con valores
int valor = 1;
for (int t = 0; t < datos.length; t++) {
for (int p = 0; p < datos[t].length; p++) {
for (int i = 0; i < datos[t][p].length; i++) {
for (int j = 0; j < datos[t][p][i].length; j++) {
datos[t][p][i][j] = valor++;
}
}
}
}
// Mostrar el tensor completo
System.out.println(Arrays.deepToString(datos));
// Acceder a un elemento específico: tiempo=1, profundidad=0, fila=1, columna=1
System.out.println("datos[1][0][1][1] = " + datos[1][0][1][1]);
}
}