La forma más primitiva de tratar con varios valores agrupados en un sólo valor son los arrays. La forma de declarar una variable tipo array es:
T[] identificador; // ejemplo int[] misNumeros;
La diferencia son los corchetes, el tipo puede ser cualquiera, igual que el número de elementos a aceptar, aunque un array tiene un número de posiciones fijas que se indican a la hora de crear el array (no la variable).
Los arrays nos permiten trabajar con varios valores juntos de un mismo tipo, aunque el número de éstos es fijo
Entonces ¿Cómo le digo cuántos elementos debe contener?
Para eso vamos a tener que crear un objeto de tipo array. Para crear objetos se usa la palabra reservadanew
, que va a apartar memoria suficiente para contener el tipo y número de elementos (entre corchetes) que definamos. Un array se crea y asigna de esta forma: int[] misNumeros;
misNumeros = new int[2];
Así tendremos en la variable misNumeros
una referencia al nuevo objeto que hemos creado que será capaz de apuntar a dos valores int. También se podría declarar un tamaño cero y se conoce como un array vacío.Si más tarde necesitáramos ampliarlo a tres, tendremos que crear otro nuevo, pues ya el array anterior no nos serviría porque su tamaño fijo es dos.
El tamaño no tiene que ser un número fijo, puede ser cualquier expresión:
String[] nombresAlumnos = new String[getNumeroAlumnos()];
¿Cómo accedo a las posiciones de un array?
Una vez que tengo espacio para un número de elementos, utilizaré una expresión de acceso de la formamiArray[indice]
, teniendo en cuenta que éstos índices deben ser del tipo int
y se empiezan a contar desde cero. Estas expresiones pueden usarse como cualquier variable. Veamos un ejemplo: misNumeros[0] = 1;
misNumeros[1] = misNumeros[0] + 1;
misNumeros[2] = 3; // error en ejecución
Debemos asignar valores del tipo exacto al declarado y asegurarnos de mantener el índice dentro del tamaño, o nuestro código se romperá mientras se ejecuta.
Debo asignar valores del tipo declarado y no usar [índices] fuera del tamaño (entre 0 y n-1)
Por otra parte, si conozco los valores desde el inicio, también puedo asignarlos declarándolos en la misma asignación;
misNumeros = new int[] { 1, 2, 3 };
Hay que tener en cuenta que cada vez que usemos new
se creará un objeto nuevo aunque se asigne a la misma variable.También se puede ver una forma más resumida (azúcar sintáctico - syntactic sugar) pero sólo si se declara la variable y se inicializa en la misma línea;
int[] misNumeros = { 1, 2, 3 };
Arrays multidimensionales
Los de arriba son arrays de una sola dimensión, pero pueden ser multidimensionales si seguimos añadiendo corchetes:int[][]
: dos dimensiones (matriz)int[][][]
: tres dimensiones (matriz cúbica)
NOTA: también puede verse declarado un array como
int a[];
No se suele utilizar, sólo se usa si se declaran varios arrays de distintas dimensiones en la misma línea como int[] a, b[];
siendo a
de una dimensión y b
de dos. Esto tratarlo como advertencia por si lo veis, pero no es normal.Para acceder a los elementos de sus distintos niveles, se concatenarán expresiones de acceso añadiendo corchetes con los índices que hagan falta:
int[][] miMatriz = new int[3][2];
miMatriz[2][0] = 1; // coloca 1 en la primera posición del tercer array de arrays[2]
System.out.println(Arrays.toString(miMatriz[2])); // imprimo el tercer array[2]
NOTA: He usado la clase java.utils.Arrays que contiene herramientas para facilitar ciertas operaciones con tipos array. Puedes ver y practicar con más métodos siguiendo su documentación.
A la hora de llamar a una posición concreta en un array multidimensional hay que tener cuidado de no exceder los límites de posiciones de cada dimensión:
miMatriz[3][0]
producirá un error igual que miMatriz[0][2]
.Recorrer un array
Una forma típica de recorrer un array es usar un buclefor
de la siguiente forma: for (int i = 0; i < misNumeros.length; i++) {
System.out.println("Posición " + i + ": " + misNumeros[i]);
}
Aquí podemos ver un miembro de los arrays que es length
, que es el encargado de decirme el tamaño del array.Para recorrer un array multidimensional usaremos los bucles for anidados que necesitemos en función de los niveles del array. Para recorrer todos los elementos de un array de dos dimensiones haremos:
public static void imprimirMatriz(int[][] matriz) {
for (int i = 0; i < matriz.length; i++) {
for (int j = 0; j < matriz[0].length; j++) {
// hacer la operación que se necesite
System.out.print(matriz[i][j] + "\t");
// uso \t para alinear las columnas
}
System.out.println(); // siguiente fila
}
}
Por último y el más usando si se quieren recorrer todos los elementos de una "colección", se puede usar el bucle for
mejorado (enhanced for
): for (T elemento : miArrayDeTipoT) {
System.out.print(elemento);
}
Con los arrays podemos usar el bucle
for
mejorado
Pero ojo, los arrays sólo apuntan a valores, no los guardan
Podemos entender que los arrays son almacenes de datos, pero en realidad son un conjunto de variables pero que en vez de tener un identificador usan expresiones de acceso como se explicó antes.Con los tipos por referencia no se harán copias aunque ocupen posiciones distintas del array.
Vamos a hacer un par de arrays que usaré para rellenar un array de arrays. Uno de ellos lo voy a poner dos veces y veremos que si se modifica cualquiera de los arrays, el cambio se produce en ellos, no en el array de arrays. Se ve más fácil en el vídeo:
int[] a = {1 , 2};
int[] b = {3 , 4};
int[][] aba = { a , b, a };
imprimirMatriz(aba);
System.out.println();
// cambiamos el primer valor
aba[0][0] = 5;
imprimirMatriz(aba);
// pero lo que cambia es "a"
// no entender como una copia
// es el mismo objeto
// se ve en esta impresion
System.out.println(Arrays.toString(aba));
System.out.println("a es: " + Arrays.toString(a));
System.out.println();
// cambiamos el tercer array
aba[2] = new int[] { 6, 7 };
imprimirMatriz(aba);
// ahora son 3 objetos distintos
System.out.println(Arrays.toString(aba));
Tenemos la siguiente salida, aunque los números que identifican los objetos serán distintos para cada uno.1 2 3 4 1 2 5 2 3 4 5 2 [[I@52e922, [I@25154f, [I@52e922] a es: [5, 2] 5 2 3 4 6 7 [[I@52e922, [I@25154f, [I@10dea4e]
NOTA (nivel avanzado): Esas cadenas de caracteres trípticos que hemos obtenido vienen del método
getName()
de la clase Class
y nos dicen de qué tipo es el objeto (en nuestro caso array de int
). Puedes leer más en la API de java.
He marcado en rojo los objetos repetidos.
Con los arrays hacemos referencia al tipo declarado, no se hacen copias de valores al asignarlos
El código donde se explica el for mejorado, creo que está equivocado. Lo correcto debería ser:
ResponderEliminarfor (T elemento : miArrayDeTipoT) {
System.out.print(elemento);
}
Cierto, primero le puse de identificador "t" y sólo cambié a "elemento" en un sitio. Lo actualizo ¡Bien visto!
EliminarPara declarar un Array, Creo que hay muchas maneras
ResponderEliminarint MisNumeros[] = new int[4];
O
int[] MisNumeros = new int[4];
O
int MisNumeros[];
MisNumeros = new int[4];
O
int[] MisNumeros;
MisNumeros = new int[4];
En realidad para declarar hay 2:
Eliminarint[] misNumeros;
int misNumerosOtraManera[];
Las dos últimas formas simplemente es repetir las dos anteriores pero separando la declaración de la asignación. Es lo que comento en la nota que lleva al enlace de la documentación de Oracle:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html#jls-10.2
Eso es,
EliminarPuse este comentario porque creo que esta declaración es la más cercana a la declaración algorítmica.