resueltos framework example español ejercicios ejemplos collection colecciones coleccion java

framework - ejercicios resueltos de colecciones en java



Colecciones Java usando comodín (7)

Con los genéricos de java que usan comodines, se le permite la declaración anterior suponiendo que solo va a leer de ella.

No tiene permitido agregar / escribir en él, porque todos los tipos genéricos deben ser eliminados en tiempo de compilación, y en tiempo de compilación no hay una manera en que el compilador sabe Lista son solo cadenas, (¡podría ser cualquier objeto incluyendo cadenas! )

Sin embargo, está autorizado a leer, ya que al menos serán objetos. No se permiten mezclar diferentes tipos en las colecciones de Java para mantener las cosas limpias y comprensibles, y esto ayuda a garantizarlo.

public static void main(String[] args) { List<? extends Object> mylist = new ArrayList<Object>(); mylist.add("Java"); // compile error }

El código anterior no le permite agregar elementos a la lista y las tarjetas comodín solo se pueden usar como firma en los métodos, de nuevo no para agregar, sino solo para acceder. En este caso, ¿qué propósito cumple lo anterior?


Digamos que tienes una interfaz y dos clases:

interface IResult {} class AResult implements IResult {} class BResult implements IResult {}

Luego tienes clases que devuelven una lista como resultado:

interface ITest<T extends IResult> { List<T> getResult(); } class ATest implements ITest<AResult> { // look, overridden! List<AResult> getResult(); } class BTest implements ITest<BResult> { // overridden again! List<BResult> getResult(); }

Es una buena solución cuando necesita "retornos covariantes", pero devuelve colecciones en lugar de sus propios objetos. La gran ventaja es que no tiene que lanzar objetos cuando usa ATest y BTest independientemente de la interfaz de ITest. Sin embargo, al usar la interfaz ITest, no puede agregar nada a la lista que se devolvió, ya que no puede determinar qué tipos de objetos contiene realmente la lista. Si estuviera permitido, podría agregar BResult a List <AResult> (devuelto como List <? Extends T>), lo cual no tiene ningún sentido.

Entonces debes recordar esto: Lista <? extends X> define una lista que se puede anular fácilmente, pero que es de solo lectura.


El punto de los tipos de comodines delimitados es su uso en las firmas de métodos para aumentar la flexibilidad de la API. Si, por ejemplo, implementa un Stack<E> genérico Stack<E> , podría proporcionar un método para enviar varios elementos a la pila de la siguiente manera:

public void pushAll(Iterable<? extends E> elements) { for(E element : elements){ push(e); } }

Comparado con una pushAll(Iterable<E> elements) sin comodín, esto tiene la ventaja de que permite que las colecciones de subtipos de E se pasen al método; normalmente eso no se permitiría porque un Iterable<String> es, de alguna manera contrariamente a la intuición, no es una subclase de Iterable<Object> .


Esto funciona:

List<? super Object> mylist = new ArrayList<Object>(); mylist.add("Java"); // no compile error

De O''Reilly''s Java Generics :

El Principio de Obtener y Poner: use un comodín de extensión cuando solo obtiene valores de nuestra estructura, use un super comodín cuando solo coloca valores en una estructura, y no use un comodín que ambos obtengan y pongan.


List<? extends Object> List<? extends Object> , que es lo mismo que List<?> , cumple el propósito de generalizar todos los tipos List<String> , List<Number> , List<Object> , etc. (de modo que todos los tipos con un tipo apropiado en lugar del ? ). Los valores de todos estos tipos se pueden asignar a una variable del tipo List<?> (Que es donde difiere de List<Object> !).

En general, no puede agregar una cadena a dicha lista. Sin embargo, puede leer Object de la lista y puede agregarle null . También puede calcular la longitud de la lista, etc. Estas son operaciones que se garantiza que funcionan para cada uno de estos tipos.

Para obtener una buena introducción a los comodines, consulte el documento Agregar comodines al lenguaje de programación Java . Es un documento académico, pero aún muy accesible.


En su libro Great ''Effective Java'' (Segunda edición), Joshua Bloch explica lo que él llama el principio de productor / consumidor para usar genéricos. La explicación de Josh debería decirle por qué su ejemplo no funciona (compilar) ...

El Capítulo 5 (Genéricos) está disponible gratuitamente aquí: http://java.sun.com/docs/books/effective/generics.pdf

Más información sobre el libro (y el autor) están disponibles: http://java.sun.com/docs/books/effective/


Genéricos de Java: comodines en colecciones

  1. se extiende
  2. súper
  3. ?

Hoy voy a explicarte cómo los comodines son útiles. Comprender este concepto es un poco difícil

Ahora supongamos que tiene una clase abstracta y tiene un método abstracto llamado paintObject ().

Now you want to use different type of collection in every child class.

Esto a continuación es el método AbstractMain.

Aquí los pasos que hemos tomado para este método principal abstracto

1. Hemos creado una clase abstracta

2. En Parámetro, hemos definido T (puede usar cualquier carácter). En este caso, cualquiera que sea la clase que implemente este método, puede usar cualquier tipo de clase. ex. La clase puede implementar un método como public void paintObject (objeto ArrayList) o public void paintObject (objeto HashSet)

3. Y también hemos utilizado E extiende MainColorTO - En este caso E extiende MainColorTo - Es claramente significa cualquier clase que desee utilizar que debe ser subclase de MainColorTo

4. Tenemos un método abstracto definido llamado paintObject (objeto T, objeto ETO) --Ahora aquí cualquiera sea la clase que implemente el método ese método puede usar cualquier clase en el primer argumento y segundo parámetro que el método tenga que usar tipo de MainColorTO

public abstract class AbstractMain<T,E extends MainColorTO> { public abstract void paintObject(T Object,E TO); }

Ahora vamos a extendernos por encima de la clase abstracta e implementar el método en la clase inferior por ej.

public class MainColorTO { public void paintColor(){ System.out.println("Paint Color........"); } } public class RedTO extends MainColorTO { @Override public void paintColor() { System.out.println("RedTO......"); } } public class WhiteTO extends MainColorTO { @Override public void paintColor() { System.out.println("White TO......"); } }

Ahora tomaremos dos ejemplos.

1.PaintHome.java

public class PaintHome extends AbstractMain<ArrayList, RedTO> { @Override public void paintObject(ArrayList arrayList,RedTO red) { System.out.println(arrayList); } }

Ahora, en la parte superior de PaintHome.java, puede verificar que hemos utilizado ArrayList en el primer argumento (como podemos tomar cualquier clase) y en el segundo argumento hemos utilizado RedTO (que se extiende MainColorTO)

2.PaintCar.java

public class PaintCar extends AbstractMain<HashSet, WhiteTO>{ @Override public void paintObject(HashSet Object,WhiteTO white) { System.out.println(Object); } }

Ahora en la parte superior de PaintCar.java puede verificar que hemos usado HashSet en el primer argumento (como podemos tomar cualquier clase) y en el segundo argumento hemos utilizado WhiteTO (que se extiende MainColorTO)

Ponint para recordar No puede usar la palabra clave super en el nivel de clase, solo puede usar extends palabra clave en el nivel de clase defination

public abstract class AbstractMain<P,E super MainColorTO> { public abstract void paintObject(P Object,E TO); }

El código anterior le dará error de compilación.