Uno de los temas que mas quebraderos de cabeza da a los desarrolladores es la construcción Java Generics o simplemente clases Genéricas.Vamos a escribir algunos artículos hablando de este tema .Para empezar con ello vamos a construir la clase Bolsa que es una clase sencilla que nos permitirá almacenar objetos de varios tipos.
Uno de los temas que mas quebraderos de cabeza da a los desarrolladores es la construcción Java Generics o simplemente clases Genéricas.Vamos a escribir algunos artículos hablando de este tema .Para empezar con ello vamos a construir la clase Bolsa que es una clase sencilla que nos permitirá almacenar objetos de varios tipos.
Esta clase tendrá un límite de objetos a almacenar . Alcanzado el limite no se podrán añadir mas .Vamos a ver su código fuente:
package com.arquitecturajava; import java.util.ArrayList; import java.util.Iterator; public class Bolsa implements Iterable { private ArrayList lista = new ArrayList(); private int tope; public Bolsa(int tope) { super(); this.tope = tope; } public void add(Object objeto) { if (lista.size() >= tope) { lista.add(objeto); } else { throw new RuntimeException("no caben mas"); } } public Iterator iterator() { return lista.iterator(); } }
En nuestro caso vamos a disponer de dos clases con las cuales rellenar la bolsa . La clase Golosina y la clase Chocolatina.
Vamos a ver su código fuente :
package com.arquitecturajava; public class Chocolatina { private String marca; public String getMarca() { return marca; } public void setMarca(String marca) { this.marca = marca; } public Chocolatina(String marca) { super(); this.marca = marca; } }
package com.arquitecturajava; public class Golosina { private String nombre; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Golosina(String nombre) { super(); this.nombre = nombre; } }
Es momento de crear un sencillo programa que llene la Bolsa de Chocolatinas y Golosinas para luego recorrer los elementos que están en la bolsa y sacarlos por pantalla.
package com.arquitecturajava; public class Principal { public static void main(String[] args) { Bolsa bolsa = new Bolsa(5); Chocolatina c = new Chocolatina("milka"); Chocolatina c1 = new Chocolatina("milka"); Chocolatina c2 = new Chocolatina("ferrero"); Golosina g1 = new Golosina("gominola"); Golosina g2 = new Golosina("chicle"); bolsa.add(c); bolsa.add(c1); bolsa.add(c2); bolsa.add(g1); bolsa.add(g2); for (Object o: bolsa) { if (o instanceof Chocolatina) { Chocolatina chocolatina = (Chocolatina) o; System.out.println(chocolatina.getMarca()); } else { Golosina golosina = (Golosina) o; System.out.println(golosina.getNombre()); } } } }
El programa funcionará correctamente, pero nos podremos dar cuenta que resulta bastante poco amigable la estructura if /else en la cual se chequean cada uno de los tipos a la hora de presentarlo por pantalla.
Java Generics
Para solventar este problema podemos construir una clase Genérica .Este tipo de clase nos permitirá definir una Bolsa de un tipo concreto . Puede ser una bolsa de Golosinas o una bolsa de Chocolatinas pero NO de las dos cosas a la vez .Esto en un principio puede parecer poco flexible pero si nos ponemos a pensar cuando programamos solemos imprimir una lista de Facturas o una lista de Compras no una lista mixta. Así pues el enfoque parece razonable. Vamos a ver el código fuente y comentarlo:
package com.arquitecturajava.genericos; import java.util.ArrayList; import java.util.Iterator; public class Bolsa < T > implements Iterable < T > { private ArrayList < T > lista = new ArrayList < T > (); private int tope; public Bolsa(int tope) { super(); this.tope = tope; } public void add(T objeto) { if (lista.size() >= tope) { lista.add(objeto); } else { throw new RuntimeException("no caben mas"); } } public Iterator < T > iterator() { return lista.iterator(); } }
La clase es un poco peculiar ya que al no saber de entrada de que tipo va a ser la bolsa debemos declarar un tipo Genérico T a nivel de clase y que será repetido en cada uno de los métodos que lo usen.
De esta manera cuando construyamos un objeto de esta clase será el momento de especificar el tipo de Bolsa que deseamos.
En el siguiente ejemplo hemos elegido “Chocolatina” como tipo para la Bolsa. De esta manera la bolsa solo admitirá este tipo de objetos.
package com.arquitecturajava.genericos; import com.arquitecturajava.Chocolatina; import com.arquitecturajava.Golosina; public class Principal { public static void main(String[] args) { Bolsa < Chocolatina > bolsa = new Bolsa < Chocolatina > (); Chocolatina c = new Chocolatina("milka"); Chocolatina c1 = new Chocolatina("milka"); Chocolatina c2 = new Chocolatina("ferrero"); bolsa.add(c); bolsa.add(c1); bolsa.add(c2); for (Chocolatina chocolatina: bolsa) { System.out.println(chocolatina.getMarca()); } } }
Acabamos de construir nuestra primera clase Generica y hemos usado un bucle forEach para recorrerla de una forma sencilla.
Tanto la explicación del concepto de Genéricos en java como también los ejemplos son bastante claros. Lo felicito. Muchas gracias.
Muchas gracias son muy claros tus post y muy informativos.
Gran post Cecilio se ve muy claro, como comentario constructivo he de decir que la condicion if (lista.size() >= tope) es incorrecta ya que en cuanto indiquemos un tope esta no se va a cumplir nunca ya que debería ser < pero muy interesante el post, mil gracias!
Buenos dias, muy buenos tus cursos y blogs. Tengo una consulta para armar una estructura de herencia en java utilizando JPA, y el metodo joined, al tratar de crear un nuevo elemento de los hijos me salta el error : Failed to read response, me genera las tablas pero no le puedo persistir los datos. Si me puedes tirar una pista por donde buscar muchas gracias.
Es muy raro el error read response? parece un error de REST mas que de jpa . Mira a ver si el error real se esta ocultando
Saludos
necesito almacenar objetos en un array con una clase generica
como hago para compararlos si deseo por ejemplo mantenerlos ordenados
gracias
Tendran todos que implementar el interface comparable o comparator
Excelente pagina, ejemplos y tutoriales.
En mi opinión, en este caso, es un poco confuso el hecho de que las soluciones no son exactamente las mismas. Estaría mejor un ejemplo donde se crea una Bolsa de solo Chocolinas con y sin Generics y luego otro ejemplo donde se crea una Bolsa mixta también con y sin Generics. ( en este ejemplo se crea una Bolsa mixta Sin generics y luego una Bolsa de solo chocolinas con Generics)
Igualmente muchas gracias por el articulo.
de nada 🙂
No entiendo bien lo que es una clase genérica y su función. y las lineas de código me confunde, estoy en proceso de aprendizaje en java.
Te explico un poco una clase generica es una estructura que normalmente almacena y gestiona objetos , puede ser una bolsa , una lista ,un arbol ,un diccionario etc. Sin embargo en principio cualquier estructura servirá en java para un tipo de objeto concreto . Por ejemplo para una galleta o para una persona .Por cada tipo de objeto necesitariamos una clase nueva . Con la construcción de un genérico necesitarías una única clase para todo los tipos de objetos . De todas maneras aprovecho a comentarte que esta explicado a detalle en mi curso de Java APIS que esta… Read more »
Hola, gracias por tus tutoriales.
Tengo una duda, ¿sería lo mismo si en vez de tener una clase golosina y chocolatina estos fueran dos ArrayList? En plan tener 2 ArrayList en la clase bolsa y separar cada una de ellas.
No se si me explico bien jaja. Sería como tener un estado de la bolsa, por ejemplo como bolsa comprada y bolsa devuelta sin tener que crear una clase comprada o devuelta.
Por poder se puede , pero probablemente encaja mejor el concepto de compra como clase y que una bolsa pueda contener una compra
Vale muchas gracias, seguiré mirando tus tutoriales.
Un saludo.
Hola Manuel, desde el punto de vista arquitectónico no creo que sería una buena idea tener una lista de cada una de estas clases, aunque de poder se puede como bien dice Cecilio Álvarez. El problema está en que, si el dia de mañana el cliente pide que en la bolsa se puedan guardar otros tipos de objetos, por poner ejemplos, “Lapices”, “Panqueques”, “Libretas”, etc… tenemos que ir y refatorizar el codigo de la clase Bolsa para agregarle mas tipos de listas, esto sin dudas es una perdida de tiempo y dinero en el mundo de desarrollo del software. Creo… Read more »
tiene que implementar obligatoriamente la interfaz IObjeto de la siguiente manera:
public class Bolsa implements Iterable{
// todo lo demas se mantiene igual en la clase
}
Iterable o IOBjeto ??
jajaja EXCELENTE observacion, yo vi lo mismo, tocará hacer el ejercicio para comprobar.
Pero el tipo GENERIC esta muy interesante eh.
La pregunta del siglo, ¿Porqué la gente odia Java si java es un lenguaje increiblemente poderoso en las manos correctas obviamente?
Ante todo gracias por esta pagina!!!!! comprendi todo menos la sentencia que se encuentra en la linea 22 y 24 de la Clase Chocolatina
Se trata del operador instanceof de Java que comprueba si el objeto es de un tipo u otro y dependiendo del tipo imprime un dato.
Cecilio, creo que se refiere al del código, que es un error del formateo en html.
En que zona exactamente?
Se refiere al   que como dijo Eleazar es un error de formateo de HTML.
creo que esta corregido 🙂
[…] Otros artículos relacionados: Entendiendo los constructores en Java ,El concepto de Java Interface ,Java Generics […]
[…] Otros artículos relacionados: Java this vs this() , Java Generics […]
[…] Otros artículos relacionados: Java Collections Views , Java List vs Set , Java Generics […]
Hola,
Una consulta.
No se reproduce con la generics class el mismo ejemplo de bolsa. Tu bolsa generica no tiene cholatinas y golosinas, solo tiene chocolatinas.
Cómo sería con una bolsa con objetos de los dos tipos?
Entiendo que la bolsa queda del tipo que le pases, pero no queda una bolsa a la que le pones cualquier cosa.
Me explico?
Saludos!
Pues tendrías que cambiar la estructura de una forma importante , ya que una lista en principio siempre es de un tipo , tendrías que crearte por ejemplo un genérico algo como class MiGenerico que almacenara dos tipos y luego esto envolverlo en una lista generica
[…] artículos relacionados: Java Generics , Java Generics […]
[…] artículos relacionados: Java Generics , Colecciones y Google Guava , Java Collections List vs […]
Excelente explicación del uso de generics, gracias por la aclaración
de nada 😉
[…] Otros Artículos relacionados: Java Lambda ForEach, Introducción a Java Lambda , Java Generics […]
– No sé si estoy en lo correcto pero te falta ponerle dentro del Constructor Bolsa cuanta reserva de memoria vas a dejar para introducir objetos dentro de la clase Bolsa
– A mi opinión sería :
new Bolsa(3);
–> 3 porque son los objetos que vas a introducir dentro de bolsa
public class Principal {
public static void main(String[] args) {
Bolsa bolsa= new Bolsa();
Chocolatina c= new Chocolatina(“milka”);
Chocolatina c1= new Chocolatina(“milka”);
Chocolatina c2= new Chocolatina(“ferrero”);
– Aun así el tutorial esta perfectamente explicado.
Si yo creo que es una opción mas flexible 🙂
Muchas gracias por la entrada, está muy bien explicado.
Saludos!!
de nada 🙂
[…] artículos relacionados: Introducción Java Generics , Java Generics WildCard, Java Generics […]
[…] Java Generics […]
[…] artículos relacionados: List vs Set , Java Generics , Java Fluid […]
[…] artículos relacionados: Java Generics , Java Generics WildCards, Java Set y […]
Muchas gracias, al fin una explicación que me deja conforme.
gracias 🙂
[…] Otros artículos relacionados : forEach vs Iterator, Java Lambda Expressions ,Uso de Generics […]
[…] artículos relacionados : Java Generics , Java Generic y WildCards , Java […]
[…] artículos relacionados: Java Generic, Java ForEach vs Iterator , Expresiones […]
[…] Otros artículos : Java Generics […]
Gracias !!! muy buena la explicación como siempre, podrías hacer algo sobre Hilos? Se te agradecería mucho (el problema es que no se cuantos hilos se deben aplicar a ciertos procesos, ¿existe una medida o algo para saber cuantos usar?) saludos y gracias por este sitio que dia con dia me gusta mucho mas
Gracias 🙂 . Me apunto la idea
Muy claro el ejemplo.
Tambien se podria usar para explicar la herencia o interfaces.
Haciendo las clases Chocolatina y Golosina, que implemente la misma interfaz o que extiendan de un mismo padre.
Asi se puediera tener una Lista (bolsa) generica, del padre o de la interfaz, y recorrer los elementos independientemente del tipo que sea…. claro tendrian que tener metodos comunes, en lugar de Marca/Nombre, podria ser Descripcion, para ambas =D
gracias