2
« en: 08 de Noviembre 2017, 01:19 »
Dejo esto por aqui para que vean la continuacion de la explicacion del compañero Kabuto.
Mira un arreglo (también llamado array, vector,...) es una agrupación de variables del mismo tipo y bajo un mismo nombre.
Si yo declaro:
int[] numeros = new int[10];
Estoy diciendo que tengo 10 variables de tipo int, y que están agrupadas bajo el nombre "numeros".
Estas variables están numeradas para que podamos apuntar a ellas una por una.
La primera está en la posición 0 y la última en este ejemplo está en la posicion 9 (del 0 al 9 hay 10 números, 10 posiciones)
La sintaxis para apuntar a una de estas posiciones, es usar el nombre del arreglo y entre corchetes el número de posición que nos interesa.
Ejemplos:
Quiero sacar por pantalla el primer número:
System.out.println("Primer numero: " + numeros[0]);
Quiero guardar en la posición 5, el mismo número que tengo en la posicion 8:
numeros[5] = numeros[8];
En lugar de números para indicar la posición, puedo usar variables de tipo int, que es de hecho lo más habitual.
Supongamos que quiero mostrar TODOS los números del arreglo.
Puedo hacer 10 system.out....
System.out.println("Numero: " + numeros[0]);
System.out.println("Numero: " + numeros[1]);
System.out.println("Numero: " + numeros[2]);
System.out.println("Numero: " + numeros[3]);
....
....
System.out.println("Numero: " + numeros[9]);
Pero esto es muy engorroso, imagina hacerlo con la agenda de 50 Contactos.
O imagina si el arreglo fuera de 10.000 posiciones... o más....
Podemos simplificarlo usando un bucle for, el cuál me irá incrementando una variable llamada i que empieza en valor 0, y le pediré que la incremente +1 mientras i sea menor que 10
for (int i = 0; i < 10; i++)
System.out.println("Numero: " + numeros[i]);
De este modo uso la variable i para apuntar a las posiciones del arreglo, en lugar de tener que poner números directamente.
En este caso, sabemos que el arreglo tiene 10 posiciones y por eso le decimos que el bucle se detenga cuando llegue a 10, ya que no existen más posiciones después de numeros[9]. Si intentamos mostrar posiciones superiores a esta, el programa dará error.
Pero, ¿que pasa si no sabemos cuanto mide el arreglo? Lo más habitual es que escribamos métodos y programas que van a recibir arreglos para operar con ellos, pero no siempre van a medir lo mismo.
El bucle for que he puesto antes solo sirve para un arreglo que tenga 10 posiciones, si recibieramos un arreglo que tiene menos posiciones, el programa daría error al pedir mostrar posiciones que no existen.
Y si recibieramos un arreglo más grande, no lo estaríamos mostrando al completo, solo veríamos las 10 primeras posiciones.
Para escribir un código que funcione con cualquier arreglo, sea cual sea su tamaño, podemos preguntarle al arreglo cual es su longitud y establecerlo como límite en el bucle for.
for (int i = 0; i < numeros.length; i++)
System.out.println("Numero: " + numeros[i]);
numeros.length nos devuelve el valor del atributo "longitud" del arreglo, así ese bucle siempre recorrerá el arreglo al completo, sea cual sea su longitud
Podemos parar el recorrido del for si se cumple una determinada condición.
Por ejemplo, supongamos que queremos recorrer el arreglo al completo, pero que se detenga si encuentra un número negativo y además nos diga en que posición lo ha encontrado:
for (int i = 0; i < numeros.length; i++)
if (numeros[i] < 0)
{
System.out.println("Numero negativo encontrado en posicion: " + i);
break;
}
Al detectar un numero negativo (menor que 0), saca un mensaje en pantalla y detiene la búsqueda usando la sentencia break. Esta sentencia "rompe" la ejecución del bucle for haciendo que se detenga antes de que se cumpla la condición impuesta al for, que era incrementar i hasta llegar a 10.
Con estas nociones, podemos ya escribir el código necesario para buscar un Contacto y mostrarlo sus datos en pantalla.
static void buscarContacto()
{
if (indiceArreglo == 0)
System.out.println("No hay Contactos registrados en la Agenda.");
else
{
System.out.print("\nIntroduzca ID del Contacto a buscar: ");
int IDaBuscar = sc.nextInt(); sc.nextLine();
for (int i = 0; i < indiceArreglo; i++)
{
if (agenda[i].getID() == IDaBuscar)
{
agenda[i].mostrarContacto();
break;
}
}
}
}
Lo primero es preguntar si indiceArreglo tiene valor 0, porque si esto es así, significa que aun no hemos registrado Contactos y no tiene sentido hacer niguna busqueda.
Recuerda que indiceArreglo, va aumentando cada vez que añadamos Contactos.
En caso de haber Contactos registrados, pedimos al usuario que nos indique el ID que quiere buscar.
Y usamos un bucle for para recorrer el arreglo de Contactos, y por cada elemento que recorremos, preguntamos si su ID coincide con el ID que nos han pedido buscar.
En caso de encontrar coincidencia, mostramos en pantalla los datos del Contacto, llamando a su propio metodo mostrarContacto().
Y tras mostrar los datos, detenemos el bucle con la sentencia break, pues ya no tiene sentido seguir buscando mas contactos, cuando ya hemos encontrado el que buscábamos.
Fíjate que en este caso, el bucle for su condición no es que la i se incremente hasta alcanzar los 50 registros del arreglo de Contactos.
LA condición es incrementarse hasta alcanzar el valor de la variable indiceArreglo.
ESto es porque, aunque hemos declarado un arreglo de 50 posiciones, dichas posiciones están "vacías" cuando el programa se inicia por primera vez.
Si permitimos preguntar por posiciones vacías, el programa se romperá.
Las posiciones las iremos llenando según vamos registrando nuevos Contactos.
Por esto es importantísima la variable indiceArreglo. Nos dice en todo momento en que posicion podemos registrar un nuevo contacto, hasta que posición podemos hacer búsquedas sin riesgo de preguntar por posiciones vacías, nos dice de inmediato si la agenda esta vacía (posicionArreglo == 0) o si la Agenda está completa (indiceArreglo == 50)
Bien, el método para buscar y mostrar Contacto ya está heho y funciona bien.
Pero aún tiene un pequeño defecto.
Al realizar la busqueda del Contacto, si lo encuentra, lo mostrará en pantalla.
Pero si no lo encuentra, no hará NADA, absolutamente NADA.
Volverá a salir el menú principal y esto no es elegante, puede resultar confuso para el usuario del programa que no está seguro de qué ha pasado con su petición de búsqueda.
En caso de no encontrar el Contacto deseado, lo ideal sería que el programa informase al usuario de que no existe ningún Contacto con ese ID.
Para ello, habría que añadir al método algún tipo de control, para que cuando el bucle de búsqueda termine, poder saber si ha encontrado o no al Contacto.
Y si no lo ha encontrado, informar al usuario.
Una forma fácil de hacerlo es usar una variable booleana que empiece con valor false.
Si encontramos el Contacto buscado, le damos valor true. Si no, conservará su valor false.
Así, al terminar el bucle podemos preguntar por el valor de esta variable, y si vemos que ha conservado su valor false, sabremos que no se encontró el Contacto, y podemos informar de ello.
static void buscarContacto()
{
if (indiceArreglo == 0)
System.out.println("No hay Contactos registrados en la Agenda.");
else
{
boolean encontrado = false;//Para controlar si encontramos o no al Contacto
System.out.print("\nIntroduzca ID del Contacto a buscar: ");
int IDaBuscar = sc.nextInt(); sc.nextLine();
for (int i = 0; i < indiceArreglo; i++)
{
if (agenda[i].getID() == IDaBuscar)
{
agenda[i].mostrarContacto();
encontrado = true;
break;
}
}
//Bucle for ha finalizado, comprobemos si ha sido porque encontró al Contacto
if (encontrado == false)
System.out.println("NO se ha encontrado ningun contado con el ID: " + IDaBuscar);
}
}
Prueba este método y verás que funciona.
Con esto también deberías poder hacer el método listarContactos(), pues es recorrer toda la Agenda (hasta donde nos diga la variable indiceArreglo) y mostrar los datos de los contactos en pantalla.
En el foro, mencioné que podría ser necesario comprobar con instanceof si el Contacto es una instancia de Persona o Empresa y hacer un casting para mostrar su datos.
Puesto que el metodo .mostrarContacto() es abstracto y comun a ambas clases, no es necesario hacer ningún casting.
Si quisieramos acceder a un método especifio de Persona (por ejemplo getEmail()) o uno de Empresa (por ejemplo getNumeroEmpresa()), entonces si que habría que hacer casting.
Esto de hacer casting, preguntar con instanceof, etc... es por el Polimorfismo de las clases.
En el foro hay un capitulo del Curso de Java donde se explica. También podemos hablar de ello más adelante.