Autor Tema: Ejercicio CU00695B Clases y métodos abstractos java  (Leído 6629 veces)

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Ejercicio CU00695B Clases y métodos abstractos java
« en: 20 de Agosto 2014, 23:12 »
Hola
Incluyo clases comprimidas en archivo adjunto CU00695B0.rar
Todas las clases comienzan con la instrucción 'package CU00695B0;'

Clases incluidas:
TestLegislator - con main
ListinLegisladores
Persona
Legislador - clase abstracta
Diputado
Senador

Centrar
Enmarcar
Mensa
Per
Repite
Validador
------------------
Saludos.
« Última modificación: 31 de Agosto 2014, 10:40 por Alex Rodríguez »

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos.
« Respuesta #1 en: 21 de Agosto 2014, 10:58 »
Hoy me has cogido con ganas de escribir. Te comento cosas que he ido viendo:

Punto 1 clase legislador:
 
Es recomendable usar siempre la estructura:
Código: [Seleccionar]

[modificador de acceso] [abstract] {class | interface | enum} NombreClase [extends + ClasePadre] [implements + Interfaz1,...,interfazN]{...}
por ejemplo:

Código: [Seleccionar]
public abstract class VehiculoPolicia extends Vehiculo implements Serializable,Cloneable{...}
En tu caso, has cambiado el orden y has echo:

Código: [Seleccionar]
abstract public class Legislador extends Persona{ ... }

Como comento, se recomienda el modificador de acceso primero.

Punto 2 sobre las clases Repite, Centrar, Enmarcar, Mensa.

Creo que todas tienen métodos similares y ademas veo que las vas usando de un proyecto a otro, no te sería mas sencillo crear una clase llamada por ejemplo... UtilConsola y arrejuntar ahí todas estas funciones y cuando quieras hacer uso de alguno de sus métodos solo tendrás una clase para manejar y no 5 distintas...?? no se, es algo que yo haría.

Por otro lado la clase Repite es exactamente igual que el método repite de la clase Enmarcar. Existen una  serie de principios en el ámbito de la programación y uno de los mas básicos es el principio DRY(Dont repeat yourself), viene a decir que no te repitas a ti mismo.
Entre estas dos clases, no se cumple este principio, por tanto creo que uno de los dos métodos te sobra.

Esta bien estas clases útiles que te estas creando, pero creo que deberías darles un repaso y aglutinar los métodos similares en una misma clase, ademas por lo que veo son todas con métodos static, por lo que aglutinarlas como te digo en una clase UtilConsola o algo así, te facilitaría saber si estas repitiendo código o funcionalidad como te esta pasando ahora.

La clase Per, que supongo es para calcular un porcentaje...Veo que la usas tanto para diputados como para senadores, y supongo que has creado la clase con intención de usarla en el futuro, Si es así deberías ponerle un nombre mas definido por ejemplo(UtilMatematicas) y ahí empezaras a crear funciones que te puedan resultar útil a lo largo de tu vida de desarrollador. La verdad ejk Per... nose, jaja.

Punto 3 en la clase Persona, me encuentro esto:

Código: [Seleccionar]
public void mostrarDatos() {
        String nombre = "Nombre: ",apellidos = "Apellidos: ",edad = "Edad: ";
        System.out.println(Repite.charNum(' ',40-nombre.length())+nombre+this.nombre);
        System.out.println(Repite.charNum(' ',40-apellidos.length())+apellidos+this.apellidos);
        System.out.println(Repite.charNum(' ',40-edad.length())+edad+this.edad+" años");
    }
    public String toString() {
        Integer datoEdad = edad;
        return "-Nombre: ".concat(nombre).concat(" -Apellidos: ").concat(apellidos).
        concat(" -Edad: ").concat(datoEdad.toString());
    }

A ver te explicaré algo que no se si sabrás, toString() es un método especial que se hereda de la clase Object(Clase padre de todas), cuando lo escribes en una clase, lo estas sobrescribiendo de la clase Object o alguna otra intermedia, por tanto debería tener anotación @Override. Al margen de esto como te decía es un método especial que se invoca cuando intentas imprimir por pantalla,escribir a un fichero,... Un objeto de ese tipo al que le has implementado el método toString().

Un ejemplo: Tenemos tu clase persona, pues te creare una clase TestPersona para que entiendas de lo que te hablo.

 
Código: [Seleccionar]
public class TestPersona {
    public static void main(String[] arg ){
        Persona p1=new Persona("pepe","gonzalez",55);
        System.out.println(p1);
       
    }
}
 
   
 Y la salida que se obtiene:
 
 
Código: [Seleccionar]
run:
-Nombre: pepe -Apellidos: gonzalez -Edad: 55
BUILD SUCCESSFUL (total time: 0 seconds)
 

 Si te fijas lo que he echo, es imprimir directamente una variable persona, y que es lo que ha pasado? Pues que automáticamente java ha buscado en la clase Persona si existía el método toString(), al existir, lo ha invocado y ha mostrado por pantalla el String que devuelve este método.
 
 Si no lo hubiera encontrado, habría ido a la clase padre a buscarlo. Por ejemplo si creo un objeto de tipo Diputado y lo intento imprimir por pantalla como no tiene método toString, va a la clase padre(Legislador) a buscarlo, como tampoco lo tiene va a su clase padre(Persona) y aquí lo encuentra, lo invoca, y se muestra por pantalla, por tanto si hacemos:
 
 
Código: [Seleccionar]
public class TestPersona {
    public static void main(String[] arg ){
       
        Diputado dip= new Diputado("pepe","gonzalez",55,"cadiz");
        System.out.println(dip);
    }
}
 
La salida por pantalla sera la misma que si fuera una persona:
 
Código: [Seleccionar]
run:
-Nombre: pepe -Apellidos: gonzalez -Edad: 55
BUILD SUCCESSFUL (total time: 0 seconds)
 

Por tanto con lo que tu has echo de escribir el método toString y ademas el mostrarDatos(), rompe de nuevo con el principio DRY, por eso te recomiendo solo que te curres el método toString() y lo uses para imprimir datos de una persona o legislador, o el objeto para el que tu quieras poder imprimirlo directamente.Por lo que yo modificaría tu clase persona para que quedara de la siguiente forma el método toString() y nos ahorraríamos el mostrar datos.
 

Código: [Seleccionar]
@Override
 public String toString() {
        String nombre = "Nombre: ",apellidos = "Apellidos: ",edad = "Edad: ";
        String cadena=Repite.charNum(' ',40-nombre.length())+nombre+this.nombre+"\n"
                +Repite.charNum(' ',40-apellidos.length())+apellidos+this.apellidos+"\n"
                +Repite.charNum(' ',40-edad.length())+edad+this.edad+" años";
               
        return cadena;
    }

Y con esto obtendrías la misma salida que con el método mostrarDatos(). De esta manera con un simple "System.out.println(variable_tipo_persona);" se imprimiría por pantalla el objeto de tipo persona con el formato que tenia en el mostrarDatos().

nota:En caso de necesitar disponer de distintos formatos de impresión, entonces si habría que crear distintos métodos para los distintos formatos. Y entonces lo tuyo si estaría bien.

Punto 4

En mi opinión, creo que si ordenaras un poco mas las cosas podrías crear cosas mas eficientes, por ejemplo el método buscar de la clase ListinLegislador. Creo que no deberia ser tan intrincado, yo por ejemplo crearía un método que devolviera un nuevo arrayList con los elementos encontrados en la búsqueda(Si puede haber mas de 1) o un objeto de tipo legislador(si solo puede haber 1) y con ese array o variable mostrar los resultados, pero eso de mezclar: "entrada de consola- proceso de búsqueda- salida por consola y tratamiento de resultado" en un mismo método no es muy recomendable.

Yo tendría por ejemplo:
 
  • Un método que obtenga la entrada de teclado del usuario(datos para realizar la búsqueda).
  • Otro método que generara un nuevo arraylist con los resultados de la búsqueda de acuerdo a ciertos parámetros.
  • Y otro método que reciba un parámetro(arraylist que será el devuelto por el método anterior).Este método se encargara de generar la salida y tratar la interacción con el usuario .

 Intentar modularizar en distintos pasos, sin pasarse tampoco... No es cuestión de tener 300 métodos cada uno para una instrucción...XDD pero si es recomendable intentar separar las distintas fases de una acción. En el caso que te explicado anteriormente, las fases podrían ser:

 
  • Obtener los datos para la búsqueda.
  • Realizar la búsqueda.
  • Tratar el resultado.
Es recomendable hacer esto por claridad y dar posibilidad a poder REUTILIZAR CÓDIGO. Imagina que  te has currado este programa para una empresa, y al mes de entregarlo, tu jefe te dice: Oye que ahora en lugar de trabajar a través de la consola, queremos la misma funcionalidad pero en un JFrame(Ventana). Pues en este caso tendrías que crear otro método buscar totalmente diferente desde cero, ya que el que tu tenias estaba echo solo para consola.

Ahora imagina que habías realizado esta separación que te he comentado, pues si lo hubieras echo, el método buscar te lo ahorrarías ya que el anterior te vale, solo tendrias que modificar los métodos para obtener los datos para la búsqueda y el método para tratar el resultado a través de una interfaz gráfica, pero el método buscar seguiría siendo el mismo. Esto es simplemente un ejemplo, y al principio cuesta el separar las funciones pero poco a poco te irás acostumbrando.

Punto 5   
 
En cuanto a tu clase validador, jeje esta bastante bien, "modo javascript onkeypress ON" XDD. te escribo una alternativa a tus métodos para que veas una forma rápida y fácil de validar. Hace uso de bloques try-catch, pero tampoco tienen mucha complicacion, simplemente intento convertir la cadena a int o float, si se convierte bien, es que la cadena era un numero valido y devuelve true. Si no se convierte, se lanza la excepción NumberFormatException y entonces se devuelve false. Como ves te ahorras bastantes if y bucles...
 
Código: [Seleccionar]
public class ValidadorNumero {
    public static boolean validarNumeroEntero(String numero){
        try{
            int n=Integer.parseInt(numero);//intento convertir cadena a entero
            return true; //Si se consigue
        }
        catch(NumberFormatException e){
            return false; //Si no se consigue
        }
    }
    public static boolean validarNumeroEntero(String numero,int valorInicial, int valorFinal){
        try{
            int n=Integer.parseInt(numero); //intento convertir cadena a entero
            if(n>valorFinal || n< valorInicial){
                throw new NumberFormatException("numero fuera de rango"); //Si esta fuera de rango, lanzo una excepcion NumberFormatException
            }
            return true; // si se consigue y el numero esta en el rango
        }
        catch(NumberFormatException e){
            return false; //Si no se consigue o el numero no esta en el rango
        }
    }
    public static boolean validarFloat(String numero){
        try{
            float n=Float.parseFloat(numero);//intento convertir cadena a float
            return true; //Si se consigue
        }
        catch(NumberFormatException e){
            return false; //Si no se consigue
        }
    }
    public static void main(String[] arg){
        System.out.println("          Validando enteros:");
        System.out.println("1331231 es entero: "+validarNumeroEntero("1331231"));
        System.out.println("sgf231 es entero: "+validarNumeroEntero("sgf231"));
         System.out.println("          Validando enteros con rangos 0-100:");
        System.out.println("12 es entero entre 0 y 100: "+validarNumeroEntero("12",0,100));
        System.out.println("155 es entero entre 0 y 100: "+ validarNumeroEntero("155",0,100));
        System.out.println("          Validando floats:");
        System.out.println("12.35 es float: "+validarFloat("12.35"));
        System.out.println("12..5 es float: "+validarFloat("12..5"));
    }
}
Como ves, de esta forma ahorras muchas operaciones al procesador y sobre todo te ahorras mucho código. Por cierto, en tu clase Validador vuelves a romper con el principio DRY en los métodos:
  • public static int entero (String entrada, int valorInicial, int valorFinal) {
  • public static int entero (String entrada) {
En el método "public static int entero (String entrada, int valorInicial, int valorFinal) {" podrias haber echo uso del otro método de esta manera:

Código: [Seleccionar]
public static int entero (String entrada, int valorInicial, int valorFinal) {
int entero = Validador.entero(entrada);
if (entero < valorInicial || entero >= valorFinal) {
return valorInicial - 1;
}
else{
return entero;
}
}
   
 
 Te hubieras ahorrado hacer 2 métodos prácticamente iguales como te ha pasado. A veces perder 30 minutos en la planificación de un ejercicio, ahorra 1 hora en el desarrollo del mismo... XDD
 
Y nada ahí tienes para entretenerte, aburrirte y todo lo que quieras y aun así seguro que me dejo algo detrás. Aunque veas que escribo mucho, comentarte que en general tu ejercicio esta bien, y todo lo que te comento son simples recomendaciones para mejorar el orden, eficiencia y claridad. Si no entiendes alguna cosilla ya sabes que por aquí andamos, Un saludo.
« Última modificación: 21 de Agosto 2014, 11:17 por dongo »

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos.
« Respuesta #2 en: 21 de Agosto 2014, 22:55 »
Hola dongo
Me voy a entretener seguro, no me aburriré
Me complace que tengas la pluma lista para enmendar entuertos (pluma o teclado, es igual)
Así mismo, el hecho de acompañar los consejos con ejemplos, hace tu exposición un verdadero libro de apuntes donde entresacar conceptos útiles.

Voy a tomarme mi tiempo en rumiarlo todo
Gracias.

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos.
« Respuesta #3 en: 26 de Agosto 2014, 22:34 »
Hola dongo
He modificado el ejercicio CU00695B siguiendo tus puntos cual guión.
Adjunto clases en archivo comprimido CU00695B1.rar
Citar
Punto 1 clase legislador:
 
Es recomendable usar siempre la estructura:

[modificador de acceso] [abstract] {class | interface | enum} NombreClase [extends + ClasePadre] [implements + Interfaz1,...,interfazN]{...}
por ejemplo:


public abstract class VehiculoPolicia extends Vehiculo implements Serializable,Cloneable{...}
- -
Rectificada la definición de la clase Legislador

public abstract class Legislador extends Persona{...}


Citar
Punto 2 sobre las clases Repite, Centrar, Enmarcar, Mensa.

Respecto a las clases con funciones desperdigadas. Las he reunido en 'UtilConsola'
La clase Repite ya no la tengo repetida (para no repetirme a mi mismo)

Citar
Punto 3 en la clase Persona, me encuentro esto:

public void mostrarDatos() {
        String nombre = "Nombre: ",apellidos = "Apellidos: ",edad = "Edad: ";
        System.out.println(Repite.charNum(' ',40-nombre.length())+nombre+this.nombre);
        System.out.println(Repite.charNum(' ',40-apellidos.length())+apellidos+this.apellidos);
        System.out.println(Repite.charNum(' ',40-edad.length())+edad+this.edad+" años");
    }
    public String toString() {
        Integer datoEdad = edad;
        return "-Nombre: ".concat(nombre).concat(" -Apellidos: ").concat(apellidos).
        concat(" -Edad: ").concat(datoEdad.toString());
    }
Dos métodos que casi hacen lo mismo 'public void mostrarDatos() ' y 'public String toString()'
He eliminado 'public void mostrarDatos()' y he modificado 'public String toString()'
Código: [Seleccionar]
@Override
    public String toString() {
        String nombre = "Nombre: ",apellidos = "Apellidos: ",edad = "Edad: ";
        String cadena = UtilConsola.repite(" ",40-nombre.length())+nombre+this.nombre+"\n" +
            UtilConsola.repite(" ",40-apellidos.length())+apellidos+this.apellidos+"\n" +
            UtilConsola.repite(" ",40-edad.length())+edad+this.edad+" años\n";
        return cadena;
    }

Citar
Punto 4
En mi opinión, creo que si ordenaras un poco mas las cosas podrías crear cosas mas eficientes, por ejemplo el método buscar de la clase ListinLegislador. Creo que no deberia ser tan intrincado, yo por ejemplo crearía un método que devolviera un nuevo arrayList con los elementos encontrados en la búsqueda(Si puede haber mas de 1) o un objeto de tipo legislador(si solo puede haber 1) y con ese array o variable mostrar los resultados, pero eso de mezclar: "entrada de consola- proceso de búsqueda- salida por consola y tratamiento de resultado" en un mismo método no es muy recomendable.
Este punto es el que me ha costado más. No encontraba la manera de hacer un array con los objetos que cumplían el criterio de búsqueda. No conseguía mas que errores, incompatibilidad de tipos y objetos que no se podian convertir.
Al final he conseguido algo. Tal vez me he liado dando la vuelta por Pontevedra, pero he conseguido que me salga con un pero.
El pero, es que me aparece un warning en la clase 'ListinLegisladores'.
Hay dos métodos nuevos en la clase 'ListinLegisladores'
public void eliminaNoOcurrenciasEnNombre(String nombre){...}
y
public Object clone(){...}

Citar
Punto 5   
 
En cuanto a tu clase validador, jeje esta bastante bien, "modo javascript onkeypress ON" XDD. te escribo una alternativa a tus métodos para que veas una forma rápida y fácil de validar. Hace uso de bloques try-catch, pero tampoco tienen mucha complicacion, simplemente intento convertir la cadena a int o float, si se convierte bien, es que la cadena era un numero valido y devuelve true. Si no se convierte, se lanza la excepción NumberFormatException y entonces se devuelve false. Como ves te ahorras bastantes if y bucles...
Tu 'alternativa' como dices, es una maravilla de simplicidad.
Recordarás que mi clase Validador devolvía valores enteros o float.
Tu versión devuelve true o false según se pueda hacer la conversión de String a int o a float
Tal vez el nombre de la clase 'tengo problemas al dar nombres a los objetos' te ha inducido a que los métodos de esta clase devuelvan un boolean.
Pero yo tozudo he adaptado tu código para devolver enteros o float según el método.
La clase modificada se llama 'Convierte'

Agradeceré tus comentarios como siempre.
Saludos.

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos.
« Respuesta #4 en: 27 de Agosto 2014, 23:40 »
Lo veo todo muchísimo mas claro, e incluso tu tienes que notarlo cuando vas a buscar un método... jeje

Bueno lo veo todo arreglado, sobre el punto 4, no buscaba que lo implementaras en este ejercicio, simplemente era una indicación para el futuro, aunque bien intentado.

El punto 4 que te remarque, es el mas difícil de controlar y planificar, yo lo que intente transmitirte, era que siempre ahí que intentar crear métodos genéricos, por ejemplo el caso que te comente del método buscar.

Tu método buscar solo es útil en tu programa, ya que mezclas comandos de consola(salida por consola,entrada por teclado  ), con la acción de buscar en si. Esto no es muy eficiente... por eso te decía como ejemplo que se podría crear un método buscar genérico y apartar esa funcionalidad de consola en otro sitio.

He cogido un método buscar de los que tenias comentado y lo he modificado de forma que hiciera lo que yo te comente.

Código: [Seleccionar]
public ArrayList<Legislador> buscaNombre(String nombre) {
       
        ArrayList<Legislador> resultado = new ArrayList<>();

        Iterator<Legislador> iL = listinLegisladores.iterator();
        Legislador tmpLeg;
        int contador = 0;
        while (iL.hasNext()) {
            tmpLeg = iL.next();
            if (tmpLeg.getNombre().contains(nombre)) {
                resultado.add(tmpLeg);
            }
        }

        return resultado;
    }
   
Si te fijas, es un simple método que recibe como tu bien intentaste un String con el nombre para la búsqueda y recorre el listín buscando todos los legisladores que coincidan, cuando encuentra uno, lo mete en el array, así hasta que termina el listín. Al terminar devuelve un arraylist con todos los legisladores que ha encontrado.

Pues bien, ya tienes el método buscar genérico, ahora puedes crear tanto métodos para tratar ese array de resultados diferentes como quieras. Por ejemplo a mi se me ocurren cuatro por ejemplo:

Nota: No los escribiré, solo es una demostración de lo que intento transmitirte   

Código: [Seleccionar]
public void mostrarPorConsola(ArrayList<Legislador> lista){
/* metodo que reciba un array list de legisladores y lo
muestra por consola*/     
}
public void mostrarEnVentana(ArrayList<Legislador> lista){
/*metodo que reciba un array list de legisladores y lo
muestra en un JFrame*/
}
public void guardarEnArchivo(ArrayList<Legislador> lista){
/*metodo que reciba un array list de legisladores y guarde
los datos en un archivo*/
}
public void guardarEnBBDD(ArrayList<Legislador> lista){
/*metodo que reciba un array list de legisladores y guarde
los datos en una bbdd */
}

Imagina que ahora invocamos al método buscar, lo haríamos de la siguiente forma.
Código: [Seleccionar]
ListinLegisladores listin=new ListinLegisladores();
//imaginamos que ya esta relleno y todo el royo...
ArrayList<Legislador> resultadoBusqueda=listin.buscaNombre("pepito");

Como ves ahora tengo un arraylist con los resultados de la Búsqueda, ahora que quieres
mostrarlo en la consola , mostrarlo en una ventana, guardarlo en la bbdd, guardarlo en un fichero o todo a la vez... XDDD

Código: [Seleccionar]
listin.mostrarPorConsola(resultadoBusqueda);
listin.mostrarEnVentana(resultadoBusqueda);
listin.guardarEnArchivo(resultadoBusqueda);
listin.guardarEnBBDD(resultadoBusqueda);

Como ves he creado un método cuya única función es buscar y punto y me devuelve un resultado que después trato con otros métodos.

Si miramos tu método buscar, en el incluyes ya la funcionalidad de mostrar y incluso la función de si el usuario quiere seguir en el menú o no... Por eso este método que tu creaste es irreutilizable, solo servirá para tu aplicación.

Por ejemplo, el método mostrarPorConsola, en ese es en el que si meterías toda esa funcionalidad que tu tienes.... tratando el arrayList de resultados...

Pero por ejemplo lo que te decía, si en un futuro tu jefe te dice oye que ahora queremos lo mismo pero en una ventana... Pues el método buscar nos seguiría sirviendo sin tener que modificarlo, solo modificarías el método mostrarPorConsola(...) que se convertiría en mostrarEnVentana(...)

La verdad que como te digo es uno de los puntos mas complicados de controlar, no te preocupes, que con el tiempo aprenderás a separar la funcionalidad.

Pero una cosa te digo, eee tu no lo haces mal, porque en los métodos de la clase UtilConsola lo has echo. Son métodos genéricos que reciben una serie de parámetros y realizan una funcion concreta, ninguno mezcla funcionalidad pues continua tb haciendolo dentro de las clases modelos que vas creando como listín, etc... Al fin y al cabo las clases son modelos, y un listín, en su método buscar, si es para buscar... no le metas nada mas, busca y después tratas el resultado....

Bueno lo que te digo, no le des muchas vueltas, porque con el tiempo te irás dando cuenta de estas cosas.

Un Saludo!

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos.
« Respuesta #5 en: 28 de Agosto 2014, 12:48 »
Hola me gustaría retractarme sobre un termino que he estado usando en los post  de este thread anteriores a este y quizá pueda dar lugar a confusiones.

A ver en los dos tochos de post anteriores, he usado la palabra genérico haciendo alusión a algo a lo que realmente no es genérico.

Con mi forma de usarlo, me he querido referir a no juntar distintas funcionalidades dentro de un método, lo que viene siendo el principio SRP:

 SRP (Simple Responsability Principle): toda clase o componente(método, estructura, enum, constructor, etc) debe tener una única responsabilidad(Por ejemplo la responsabilidad de Buscar) y todas sus funciones deben orientarse hacia ésta.

A este concepto es a lo que me refiero con genérico en en mis post anteriores.



En cambio existen una serie de técnicas en java que nos permiten hacer que una clase trabaje con distintos tipos de objetos y es usando tags(<>) junto al nombre de la clase.

Por ejemplo la Clase ArrayList<> funciona de esta manera, ya que al crear un objeto de la clase, tenemos que indicarle también con que tipo de objetos vamos a trabajar.

Me gustaría dejar esto claro, ya que quizá alguien halla podido interpretar este termino de manera incorrecta.

Para terminar pondré un ejemplo de como si sería un método buscar()  genérico:

Archivo BuscarGenerico.java
Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class BuscarGenerico<T> {

    public List<T> buscar(List<T> lista, T elementoABuscar) {
        List<T> resultado = new ArrayList<>();
        Iterator<T> iL = lista.iterator();
        T tmp;
        while (iL.hasNext()) {
            tmp = (T) iL.next();
            if (tmp instanceof String) {
                String elementoLista = (String) tmp;
                String elementoBuscado = (String) elementoABuscar;
                if (elementoLista.contains(elementoBuscado)) {
                    resultado.add(tmp);
                }
            } else {
                if (tmp.equals(elementoABuscar)) {
                    resultado.add(tmp);
                }
            }
        }

        return resultado;
    }
}

Fichero Persona.java

Código: [Seleccionar]
public class Persona {

    String nombre;
    String apellido;

    public Persona(String param1, String param2) {
        this.nombre = param1;
        this.apellido = param2;
    }

    @Override
    public boolean equals(Object p) {
        Persona tmp = (Persona) p;
        if ((this.nombre.equals(tmp.nombre)) && (this.apellido.equals(tmp.apellido))) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return nombre + " " + apellido;
    }
}

Fichero TestBuscarGenerico.java

Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class TestBuscarGenerico {

    public static void main(String[] arg) {
        ArrayList<String> lista = new ArrayList<>();
        String cadena;
        //Usando el metodo para buscar cadenas
        for (int i = 0; i < 60; i++) {
            if (i % 2 == 0) {
                cadena = "Posicion par " + i;
                lista.add(cadena);
            } else {
                cadena = "Posicion impar " + i;
                lista.add(cadena);
            }
        }
        ArrayList<String> resultado = new ArrayList<>();
        String cadenaABuscar = "1";
        BuscarGenerico<String> utilBuscar = new BuscarGenerico<>();
        resultado = (ArrayList) utilBuscar.buscar(lista, cadenaABuscar);

        for (String s : resultado) {
            System.out.println("esta cadena a sido encontrada: " + s);
        }
        //Usando el metodo para buscar numeros
        ArrayList<Integer> listaNumeros = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            listaNumeros.add(i);
        }
        BuscarGenerico<Integer> utilBuscarNumero = new BuscarGenerico<>();
        ArrayList<Integer> resultadoNumeros = (ArrayList<Integer>) utilBuscarNumero.buscar(listaNumeros, 57);

        for (Integer i : resultadoNumeros) {
            System.out.println("Número encontrado: " + i);
        }
        //Usando el metodo para buscar personas
        ArrayList<Persona> listaPersonas = new ArrayList<>();
        Persona p1 = new Persona("Felipe", "gonzalez");
        listaPersonas.add(p1);
        Persona p2 = new Persona("perico", "buengustos");
        listaPersonas.add(p2);
        Persona p3 = new Persona("filipo", "octavo");
        listaPersonas.add(p3);
        Persona p4 = new Persona("manuel", "maqueda");
        listaPersonas.add(p4);
        BuscarGenerico<Persona> utilBuscarPersona = new BuscarGenerico<>();
        Persona personaABuscar = new Persona("perico", "buengustos");
        ArrayList<Persona> resultadoPersonas = (ArrayList<Persona>) utilBuscarPersona.buscar(listaPersonas, personaABuscar);
        for (Persona p : resultadoPersonas) {
            System.out.println("Persona Encontrada: " + p);
        }

    }

}

Y esto que he puesto(BuscarGenerico) si es una una clase Genérica.

Bueno, espero que el concepto haya quedado mas o menos claro y que no haya confusiones.

Bueno un saludo!
« Última modificación: 28 de Agosto 2014, 13:20 por dongo »

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos java
« Respuesta #6 en: 02 de Septiembre 2014, 22:19 »
Hola dongo.
He visto tu último post.
Desde mi punto de vista, es una verdadera joya.
Como diría el difunto Peret 'La etiqueta/tag tiene poder'

Una clase para buscar cualquier objeto en una lista. Cualquier objeto. Ay es na.
Y no solo eso, si no que cuando el objeto que se busca es un String, pemite Buscar dentro del String la porción de texto deseada.

Cuando yo sepa hacer algo parecido, me voy a pedir buscar donde cae el Gordo de Navidad.

Gracias.

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00695B Clases y métodos abstractos java
« Respuesta #7 en: 04 de Septiembre 2014, 20:24 »
Paciencia, paciencia, todo llegará, jejeje y claro que aprenderás a realizar clases genéricas, son muy útiles, aun así si decides echar el gordo y te toca....Acuérdate de los pobres, jaja. Un saludo!!

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".