Hola a todos, hoy explicare que son los genéricos y para que se usan en Java.
Los genéricos nos indica que tipo de datos puede manejar una estructura de datos, como una lista enlazada. Es lo que se conoce como clases parametrizadas, donde le indicamos con una clase entre <>.
En principio, no es estrictamente necesario que una clase parametrizada, se le indique una clase, permitiéndonos añadir varios tipos de valores pero esto nos dará muchos problemas en el futuro, ya que para acceder a un nodo de esta lista se debe hacer un casting del mismo tipo para que pueda ser accedido.
Vamos a ver un simple ejemplo:
import java.util.ArrayList; public class ArrayListApp { public static void main(String[] args) { ArrayList<String> listaParametrizada=new ArrayList<>(); ArrayList listaNoParametrizada=new ArrayList(); //Solo podemos insertar String listaParametrizada.add("hola"); listaParametrizada.add("adios"); listaParametrizada.add(new Integer(5)); //Nos dara un error //Podemos insertar cualquier tipo de valor listaNoParametrizada.add(new Integer(3)); listaNoParametrizada.add("¿Como vas?"); //No es necesario hacer un casting String v1=listaParametrizada.get(0); String v2=listaParametrizada.get(0); //Es necesario hacer un casting int v3=(int)listaNoParametrizada.get(0); String v4=(String)listaNoParametrizada.get(1); } }
También se pueden hacer métodos y clases genéricas.
Mira este ejemplo de nuestra ListaEnlazada:
/** * * @author DiscoDurodeRoer * @param <T> */ public class Nodo<T> { private T dato; private Nodo<T> siguiente; /** * Constructor por defecto */ public Nodo(){ siguiente=null; } /** * Le pasamos un dato al nodo * @param p */ public Nodo(T p){ siguiente=null; dato = p; } /** * Le pasamos un dato y su siguiente nodo al nodo * @param t Dato a insertar * @param siguiente Su sisguiente nodo */ public Nodo(T t, Nodo<T> siguiente){ this.siguiente=siguiente; dato = t; } public T getDato() { return dato; } public void setDato(T dato) { this.dato = dato; } public Nodo<T> getSiguiente() { return siguiente; } public void setSiguiente(Nodo<T> siguiente) { this.siguiente = siguiente; } }
Ahora, vamos con la clase ListaEnlazada.
/** * @author DiscoDurodeRoer * @param <T> * Lista enlazada simple */ public class ListaEnlazada<T>{ //Atributos private Nodo<T> primero; /** * Constructor por defecto */ public ListaEnlazada(){ listaVacia(); } /** * Vacia la lista */ private void listaVacia(){ primero = null; } /** * Indica si la lista esta vacia o no * @return True = esta vacia */ public boolean estaVacia(){ return primero == null; } /** * Inserta un objeto al principio de la lista * @param t Dato insertado */ public void insertarPrimero(T t){ Nodo<T> nuevo = new Nodo<>(t); if (!estaVacia()){ //Sino esta vacia, el primero actual pasa a ser // el siguiente de nuestro nuevo nodo nuevo.setSiguiente(primero); } //el primero apunta al nodo nuevo primero=nuevo; } /** * Inserta al final de la lista un objeto * @param t Dato insertado */ public void insertarUltimo(T t){ Nodo<T> aux = new Nodo<>(t); Nodo<T> rec_aux; if (estaVacia()) { insertarPrimero(t); }else { rec_aux = primero; //Buscamos el ultimo nodo while(rec_aux.getSiguiente() != null){ rec_aux=rec_aux.getSiguiente(); } //Actualizamos el siguiente del ultimo rec_aux.setSiguiente(aux); } } /** * Quita el primer elemento de la lista */ public void quitarPrimero(){ Nodo<T> aux; if (!estaVacia()){ aux=primero; primero = primero.getSiguiente(); aux=null; //Lo marcamos para el recolector de basura } } /** * Quita el ultimo elemento de la lista */ public void quitarUltimo(){ Nodo<T> aux=primero; if(aux.getSiguiente()==null) //Aqi entra, si la lista tiene un elemento listaVacia(); if(!estaVacia()) { aux=primero; //Buscamos el penultimo, por eso hay dos getSiguiente() while(aux.getSiguiente().getSiguiente() != null){ aux=aux.getSiguiente(); } //Marcamos el siguiente del antepenultimo como nulo, eliminando el ultimo aux.setSiguiente(null); } } /** * Devuelve el último elemento de la lista * @return Último elemento */ public T devolverUltimo(){ T elemen = null; Nodo<T> aux; if (!estaVacia()){ aux = primero; //Recorremos while(aux.getSiguiente() != null){ aux = aux.getSiguiente(); } elemen = aux.getDato(); } return elemen; } /** * Devuelve el primer elemento de la lista * @return Primer elemento, null si esta vacia */ public T devolverPrimero(){ T elemen = null; if (!estaVacia()){ elemen = primero.getDato(); } return elemen; } /** * Devuelve el número de elementos de la lista * @return Número de elementos */ public int cuantosElementos(){ Nodo<T> aux; int numElementos=0; aux = primero; //Recorremos while(aux != null){ numElementos++; aux = aux.getSiguiente(); } return numElementos; } /** * Devuelve el dato del nodo en la posicion pos * @param pos * @return dato del nodo en la posicion indicada */ public T devolverDato(int pos){ Nodo<T> aux=primero; int cont=0; T dato=null; if(pos<0 || pos>=cuantosElementos()){ System.out.println("La posicion insertada no es correcta"); }else{ //recorremos while(aux!=null){ if (pos == cont){ //Cogemos el dato dato=aux.getDato(); } aux=aux.getSiguiente(); cont++; } } return dato; } /** * Devuelve el nodo de la posicion indicada * @param pos * @return Nodo de la posicion indicada */ public Nodo<T> devolverNodo(int pos){ Nodo<T> aux=primero; int cont=0; if(pos<0 || pos>=cuantosElementos()){ System.out.println("La posicion insertada no es correcta"); }else{ //recorremos while(aux!=null){ if (pos == cont){ //Devuelvo aux, con esto salimos de la función return aux; } //Actualizo el siguiente aux=aux.getSiguiente(); cont++; } } return aux; } /** * Inserta un nuevo nodo en la posicion indicada con el su dato * @param pos * @param dato */ public void introducirDato(int pos, T dato){ Nodo<T> aux=primero; Nodo<T> auxDato=null; //Debemos crear un nodo para insetar el dato Nodo<T> anterior=primero; //Debemos crear un nodo para insetar el dato int contador=0; if(pos<0 || pos>cuantosElementos()){ System.out.println("La posicion insertada no es correcta"); }else{ if(pos==0){ insertarPrimero(dato); }else if(pos==cuantosElementos()){ insertarUltimo(dato); }else{ //Recorremos while(aux!=null){ if (pos == contador){ //Creo el nodo auxDato=new Nodo<>(dato, aux); //El siguiente del anterior a aux es auxDato anterior.setSiguiente(auxDato); } //Actualizo anterior anterior=aux; contador++; aux=aux.getSiguiente(); //Actualizo siguiente } } } } /** * Modifica el dato indicado en el nodo de la posicion indicada * @param pos * @param dato */ public void modificarDato(int pos, T dato){ Nodo<T> aux=primero; int cont=0; if(pos<0 || pos>=cuantosElementos()){ System.out.println("La posicion insertada no es correcta"); }else{ //Recorremos while(aux!=null){ if (pos == cont){ //Modificamos el dato directamente aux.setDato(dato); } cont++; aux=aux.getSiguiente(); //Actualizamos } } } /** * Borra un elemento de la lista * @param pos Posición de la lista que queremos borrar */ public void borraPosicion(int pos){ Nodo<T> aux=primero; Nodo<T> anterior=null; int contador=0; if(pos<0 || pos>=cuantosElementos()){ System.out.println("La posicion insertada no es correcta"); }else{ while(aux!=null){ if (pos == contador){ if (anterior==null){ primero = primero.getSiguiente(); }else { //Actualizamos el anterior anterior.setSiguiente(aux.getSiguiente()); } aux=null; }else{ anterior=aux; aux=aux.getSiguiente(); contador++; } } } } /** * Devuelve el primer el elemento y lo borra de la lista * @return Primer elemento */ public T devolverYBorrarPrimero(){ T dato=devolverPrimero(); quitarPrimero(); return dato; } /** * Indica la posición del primer dato que se encuentre * @param t dato buscado * @return Posición del dato buscado, -1 si no se encuentra o esta vacia */ public int indexOf (T t){ Nodo<T> aux=primero; if (estaVacia()){ return -1; }else{ int contador=0; boolean encontrado=false; //recorremos, cuando encontrado=true, sale del bucle while(aux!=null && !encontrado){ if(t.equals(aux.getDato())){ //Cambiamos a true encontrado=true; }else{ contador++; //actualizamos aux=aux.getSiguiente(); } } if(encontrado){ return contador; }else{ //no se ha encontrado return -1; } } } /** * Indica la posición del primer dato desde la posicion indicada * @param t dato buscado * @param pos * @return Posición del dato buscado, -1 si no se encuentra o esta vacia */ public int indexOf (T t, int pos){ Nodo<T> aux; if (estaVacia()){ return -1; }else{ int contador=pos; boolean encontrado=false; //Empezamos desde el nodo correspondiente aux=devolverNodo(pos); //recorremos, cuando encontrado=true, sale del bucle while(aux!=null && !encontrado){ if(t.equals(aux.getDato())){ //Cambiamos a true encontrado=true; }else{ contador++; //Actualizamos aux=aux.getSiguiente(); } } if(encontrado){ return contador; }else{ return -1; } } } /** * Indica si un dato existe en la lista * @param t Dato a comprobar * @return Si el dato existe, devuelve true */ public boolean datoExistente(T t){ boolean existe=false; Nodo<T> aux=primero; while(aux!=null && !existe){ if(aux.getDato().equals(t)){ existe=true; } //Actualizamos aux=aux.getSiguiente(); } return existe; } /** * Muestra el contenido de la lista */ public void mostrar(){ System.out.println("Contenido de la lista"); System.out.println("---------------------"); Nodo<T> aux=primero; while(aux!=null){ System.out.println(aux.getDato());//mostramos el dato aux=aux.getSiguiente(); } } /** * Devuelve el contenido de la lista en un String * @return contenido de la lista */ @Override public String toString(){ String contenido=""; Nodo<T> aux=primero; while(aux!=null){ contenido=aux.getDato()+"\n"; //guardamos el dato aux=aux.getSiguiente(); } return contenido; } }
Fijate que hace el mismo efecto que en el ejemplo anterior con ArrayList.
Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.
El primer apartado del tema de «estructuras dinámicas» (http://www.discoduroderoer.es/listas-enlazadas-en-java/) no se encuentra disponible
¿Podrían por favor resubirlo?
Gracias de antemano.
Sigue sin estar disponible…..
public String toString(){
String contenido=»»;
Nodo aux=primero;
while(aux!=null){
contenido=aux.getDato()+»\n»; //guardamos el dato
aux=aux.getSiguiente();
}
return contenido;
}
la mayoria de tu codigo tiene error, por ejemplo el override del ToString(), solo muestra el ultimo dato