Arrays Unidimensionales
Introducción
Vamos a ver la primera estructura de datos del curso.
Como estructura definiremos como una colección de objetos, que se agrupan o se almacenan juntos.
Los arrays tienen varios nombres que podéis encontraros: vector y arreglo.
Estos objetos o elementos que se agrupan tienen un índice o clave para poder acceder a ellos. Y estos objetos deben ser del mismo tipo (Clases o tipos primitivos).
La forma de un array unidimensional es la de un String que habéis estado utilizando hasta ahora, pero ahora no sólo podemos guardar unos caractéres juntos sino todo tipo de objetos.
Un array puede tener más de una dimensión, pero esto lo veremos más adelante. Lo que hay que tener claro que cada elemento del array es referenciado por la posición que ocupa dentro del índice. Es una indexación directa, y no hay necesidad de recorrer toda la estructura de datos. Importante: la primera posición del array es la 0.
Otro aspecto muy relavante es que los arrays son estructuras de datos estáticas, es decir debemos reservar el tamaño máximo del array (número de elementos que podemos almacenar o referenciar). Esta tamaño no podrá ser modificado, más adelante veremos estructuras de datos dinámicas.
Declaración
En la declaración de un array debemos indicar que tipo de objetos queremos almacenar en el, y se usar los corchetes: tipo [] nombre;
int [] id_productos;
String [] nombres;
Cliente [] listadosCliente;
Este paso sólamente crear la variable que va a referenciar un array.
Inicialización
Una vez que tenemos la “variable array”, tenemos que crear el array y se reserva la memoria para el. En este paso hay que indicar el tamaño que va a tener: nombre = new tipo [tamaño];
id_productos = new int [10]; // acabamos de crear un array de 10 números enteros
nombre = new String [5];
Por supuesto la declaración y la inicialización lo podéis hacer en una misma línea, pero es interesante diferenciar las dos fases:
Cliente [] listadoClientes = new Cliente [20]; // hemos creado un array unidimensional para 20 objetos cliente
float [] temp_maxs = new float [10];
Ojo!: al crear el array no creamos los objetos que van a ir dentro del array, sólo reservamos memoria para las referencias de ellos.
- Para tipos numéricos -> 0
- Para tipo boolean -> false
- Para objetos -> null
Inicialización + Declaración + Creación
Java nos permite al crear un array inicializar con valores en el momento de la declaración. Esta es la forma:
De esta forma no es necesario indicarle Java el tamaño del array. Ya se reserva y sea crea las posiciones necesarias en base a los valores indicados. Ejemplo:
String [] dias_semana = {"Lunes", "Martes", "Miércoles", "Viernes"};
Lectura y escritura de los elementos
Para la lectura como para asignar un valor/objeto a una posición de un array es necesario un índice que representará la posición, se usa los corchetes para ello:
dias_semana[2] = "Sabado"; // escritura
System.out.println(dias_semana[3]); //lectura
Para no cometer errores de acceso o de escritura debes siempre saber que el índice empieza en 0 y que la máxima posición de un array viene determinada por la propiedad length:
int [] lista = new int[10];
System.out.println (lista.length);
En caso de acceder a una posición del array que no existe se producirá la excepción ArrayIndexOutOfBoundsException en tiempo de ejecución.
Acceso y recorrer (bucle for-each)
Ya sabemos acceder a través de un índice a una posición concreta de un array, pero a veces necesitamos recorrer el array por completo de principio a fin.
- Usando un for normal controlando los indices:
int [] numbers = {5, 3, 9, 2, 8};
for (int i=0; i<numbers.length; i++){
System.out.println(numbers[i]);
}
- Usando el for-each:
for (int n : numbers){
System.out.println(n);
}
Fíjate bien cómo está construido este for porque ahí está la clave: int n : numbers. La variable numbers es el array y la variable n es un entero que toma el valor de un elemento del array en cada iteración. En este caso el array es de tipo int, por eso la variable n también lo es. Si el array almacenase datos de tipo float esta variable también tendría que ser de ese tipo. Siempre debe coincidir el tipo de esta variable con el tipo del array. Es un “for” más automático y cómodo de usar, pero no nos permite hacer saltos, o iteraciones diferentes -> siempre es del inicio al final salvo que uséis break o continue.
- También podemos usar while, pero lógicamente debemos controlar el índice:
int [] numbers = {5, 3, 9, 2, 8};
int i=0;
while (i<numbers.length){
System.out.println(numbers[i]);
i++;
}
Ejercicio 1
Crea un programa que cuente cuántos números pares e impares hay en un array.
Ejercicio 2
Eliminar duplicados: Crea un programa que elimine los elementos duplicados de un array. Ese array estará compuesto de números enteros. Para facilitar la tarea ordénado lo previamente.
Prueba una función estática de la clase Arrays (ya indagaremos en ellas): Arrays.sort(int [] a)
Una vez tengas “limpiado” el array puedes crear uno nuevo con el tamaño correcto con: Arrays.copyOf(array, indice)
Referencias
Cómo ya sabemos, los arrays son objetos y sus variables, contienen unicamente referencias a dichos objetos en memoria. Entonces si asignáis una variable array a otro no estamos copiando un array, estan ambas variables apuntando al mismo array. Ejemplo:
int[] ar1 = {3,7,8,9};
int[] ar2 = ar1;
ar2 [2] = 99;
for ( int i : ar1){ Syste.out.println(i);}
Ejercicio 3
Desarrolla una pequeña aplicación de agenda con unos contactos. La información de los contactos será: nombre, apellido, email y teléfono Se crean varios contactos de ejemplo internamente. Tendremos un máximo de 20 contactos, y las funcionalidades a implementar son las siguientes:
- Mostrar todos los contactos por pantalla.
- Búsqueda de contacto por email y actualizarlo (entrada de datos por teclado).
- Validación del email: que tenga sólo una ‘@’
Método varargs
Un método varargs es aquel que recibe un número variable de argumentos. Fue introducido en Java 5 y es aplicable también a constructores. Es conocido también como método de argumentos variables. Se caracteriza por utilizar 3 puntos o puntos suspensivos en la declaración de los argumentos. Sintásis -> tipo de datos … nombre argumento Estos argumentos variables son un array unidimensional normal que podemos recorrer. Y el tipo de elementos del array es el tipo a la izquierda de tres puntos suspensivos:
public static int max(int... valores){
int max = Integer.MIN_VALUE;
for(int valor : valores) {
if(valor > max)
max = valor;
}
return max;
}
Restriciones para varargs:
- No puede haber más de 1 vargar en la cabecera del método.
- Si hay otros argumentos en la cabecera, el varargs debe colocarse al final:
public static int max(int... valores, String msg) // ERROR
public static int max(String msg, int...valores) // CORRECTO
- Si hay sobrecarga de metodos con varargs, Java siempre priorizará el método con los parámetros más exactos. Compruébalo!