siempre he utilizado es el object y estoy tratando de entender las ventajas de los genericos,
ya se que sirve para asegurarse de tener listas homogéneas y así ahorrase el cast ala salida y ayuda a evitar errores...entre otras cosas...
pero no estoy seguro que mas utilidad tenga, y no tengo muy claro donde es que es util utilizarla .
Una clase para crear y realizar diferentes acciones con arboles que utilizaba Object la cambie a ese tipo generico quedando asi:
/**
Código:
si es necesario utilizar genericos aqui?* @version 1.00 2010/4/1 *////arbol binario de busqueda public abstract class CArbolBB <T>{ // atributos del arbol binario protected CNodo raiz=null;// raiz del arbol binario //Nodo de un arbol binario private class CNodo { private T datos; private CNodo izquierdo; private CNodo derecho; public CNodo(){} } //Posibles errores que se pueden dar relativos a un nodo public static final int CORRECTO = 000; public static final int NO_DATOS = 100; public static final int YA_EXISTE = 101; public static final int NO_EXISTE = 102; public CArbolBB() {} // metodo para redefinir, comaparando por el atributo que necesitemos public abstract int comparar(T obj1,T obj2); //metodo para redifinir, realizar con el nodo visitado public abstract void procesar(T obj); //metodo redefinir de tal forma que invoque a inorden con los argumentos deseados public abstract void visitarInorden(); public T buscar(T obj) { // El método buscar permite acceder a un determinado nodo. CNodo actual = raiz; int nComp = 0; // Buscar un nodo que tenga asociados los datos dados por obj while( actual != null ) { if(( nComp = comparar( obj, actual.datos ))== 0) return( actual.datos ); // CORRECTO (nodo encontrado) else if ( nComp < 0 ) // buscar en el subárbol izquierdo actual = actual.izquierdo; else // buscar en el subárbol derecho actual = actual.derecho; } return null; // NO.EXISTE } public int insertar(T obj) { // El método insertar permite añadir un nodo que aún no está // en el árbol. CNodo ultimo = null, actual = raiz; int nComp = 0; if( obj == null ) return NO_DATOS; // Comienza la búsqueda para verificar si ya hay un nodo con // estos datos en el árbol while (actual != null) { if ((nComp = comparar( obj, actual .datos ))== 0) break; // se encontró el nodo else { ultimo = actual; if( nComp < 0 ) // buscar en el subárbol izquierdo actual = actual.izquierdo; else // buscar en el subárbol derecho actual = actual.derecho; } } if ( actual == null ) // no se encontró el nodo, añadirlo { CNodo nuevoNodo = new CNodo(); nuevoNodo.datos = obj; nuevoNodo.izquierdo = nuevoNodo.derecho = null; // El nodo a añadir pasará a ser la raíz del árbol total si // éste está vacio, del subárbol izquierdo de "último" si la // comparación fue menor, o del subárbol derecho de "último" si // la comparación fue mayor. if ( ultimo == null ) // árbol vacio raiz = nuevoNodo; else if ( nComp < 0 ) ultimo.izquierdo = nuevoNodo; else ultimo.derecho = nuevoNodo; return CORRECTO; } // fin del bloque if ( actual = null ) else // el nodo ya existe en el árbol return YA_EXISTE; } public T borrar(T obj){ // El método borrar permite eliminar un nodo del árbol. CNodo ultimo = null, actual = raiz; CNodo marcado = null, sucesor = null; int nAnteriorComp = 0, nComp = 0; if (obj == null) return null; // N0_DAT0S // Comienza la búsqueda para verificar si hay un nodo con // estos datos en el árbol. while( actual != null ) { nAnteriorComp = nComp; // resultado de la comparación anterior if (( nComp = comparar( obj, actual.datos )) == 0) break; // se encontró el nodo else { ultimo = actual ; if ( nComp < 0 ) // buscar en el subárbol izquierdo actual = actual.izquierdo; else // buscar en el subárbol derecho actual = actual.derecho; } } // fin del bloque whlle ( actual !- nuil ) if ( actual != null ){ // se encontró el nodo marcado = actual ; if (( actual.izquierdo == null && actual.derecho == null )) // se trata de un nodo terminal (no tiene descendientes) sucesor = null; else if ( actual.izquierdo == null ) // nodo sin subárbol izq. sucesor = actual.derecho; else if ( actual.derecho == null ) // nodo sin subárbol derecho sucesor = actual.izquierdo; else // nodo con subárbol izquierdo y derecho { // Referencia del subárbol derecho del nodo a borrar sucesor = actual = actual.derecho; // Descender al nodo más a la izquierda en el subárbol // derecho de este nodo (el de valor más pequeño) y hacer // que el subárbol izquierdo del nodo a borrar sea ahora // el subárbol izquierdo de este nodo. while ( actual.izquierdo != null ) actual = actual.izquierdo; actual.izquierdo = marcado.izquierdo; } // Eliminar el nodo y rehacer los enlaces if ( ultimo != null ) { if( nAnteriorComp < 0 ) ultimo.izquierdo = sucesor; else ultimo.derecho = sucesor; } else raiz = sucesor; return marcado.datos; // CORRECTO // "marcado" será enviado a la basura } else // el nodo buscado no está en el árbol return null; // NO_EXISTE } public void inorden(CNodo r, boolean nodoRaiz) { //orden de visita: subarbol izquierdo, raiz y subarbol derecho CNodo actual = null; if(nodoRaiz) actual = raiz;// partir de la raiz else actual = r; // partir de un nodo cualquiera if(actual != null) { inorden(actual.izquierdo,false); // visitar subarbol izquierdo procesar(actual.datos); //procesar los datos del nodo visitado inorden(actual.derecho, false);//visitar subarbol derecho } } }
otra duda me resulto cuando fui a redefinir los metodos abstractos en una subclase y no pude utilizar la misma T asi:
Código:
como ven tuve que volver a utilizar Object por que no puedo utilizar genéricospublic abstract class Redefinir_CArbolBB_para_Nota extends CArbolBB{ public int comparar(Object obj1,Object obj2){ if(((objetoNota)(obj1)).ObtenerNota()==((objetoNota)(obj2)).ObtenerNota()) return 0; else if(((objetoNota)(obj1)).ObtenerNota()<((objetoNota)(obj2)).ObtenerNota()) return -1; else return 1; } public void procesar(Object obj){ System.out.println("Nombre estudiante "+((objetoNota)(obj)).ObtenerNombre()); System.out.println("Curso estudiante "+((objetoNota)(obj)).ObtenerCurso()); System.out.println("Nota estudiante "+((objetoNota)(obj)).ObtenerNota()); } //metodo redefinir de tal forma que invoque a inorden con los argumentos deseados public void visitarInorden(){ inorden(null,true); } }
¿por que no se puede?
y la otra duda fue cuando en la clase principal voy hacer la declaración para que el árbol sea homogéneo asi:
Código:
me marca error en la declaración del objeto: "Redefinir_CArbolBB_para_Nota"public class Nota{ public static void main(String arg[]){ Redefinir_CArbolBB_para_Nota<objetoNota> Arbol=new Redefinir_CArbolBB_para_Nota<objetoNota>(); objetoNota obj[]=new objetoNota[6]; for(int i=0;i<6;i++){ System.out.print("Nombre estudiante "+(i+1)+": "); String N=Leer.leercadena(); System.out.print("Curso estudiante "+(i+1)+": "); int C=Leer.leerint(); System.out.print("Nota estudiante "+(i+1)+": "); double NO=Leer.leerint(); obj[i]=new objetoNota(N,NO,C); Arbol.insertar(obj[i]); } Arbol.visitarInorden(); } }
bueno me surgen muchas preguntas:
¿tiene que ver que el objeto sea de la subclase del árbol binario?
¿los genéricos solo sirven para las listas lineales ?
¿o solo funcionan con ciertas clases que vienen con java?
¿si estoy entendiendo bien la utilidad de los genéricos o estoy bien perdido?
Agradezco al que me ayude con estas dudas...