SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

84
SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS

Transcript of SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Page 1: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

SUN CERTIFIED JAVA PROGRAMMER (SCJP)

CAPÍTULO 7: COLECCIONES Y GENÉRICOS

Page 2: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Objetivos de Certificación

• Overriding de los métodos hashCode() e equals().

• Determinar el uso apropiado de colecciones (interfaces y clases), incluyendo el uso de la interface Comparable.

• Uso del Framework Collections.

Page 3: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Métodos de la clase Object cubiertos en el examen

Page 4: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Método toString()

• Usado para leer detalles útiles del objeto.• Cuando no es sobrescrito, imprime el nombre

de la clase, seguido del @ y la representación en hexadecimal (sin-signo) del hashcode del objeto.

Ej: HardToRead h = new HardToRead();System.out.println(h); // imprime : HardToRead@a47e0

Ejemplo OverridingToString.java

Page 5: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Overriding equals()

• Recordemos que la clase String y las clases wrapper sobreescriben el método equals() para poder comparar dos objetos (del mismo tipo) y revisar si sus contenidos son significativamente equivalente.

• Cuando necesitas saber si dos referencias son identicas se usa el ==. Pero cuando necesitas saber si dos objetos (no las referencias) son iguales, se utiliza el método equals().

Page 6: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• En la clase Object, equals() usa solamente el operador == para realizar la comparación, por ello mientras no se sobreescriba este método, dos objetos serán considerados iguales si sus referencias apuntan al mismo objeto.

• Entonces, para que un objeto pueda ser usado como key en un hashtable, etc; se debe sobreescribir el método equals(), para que dos instancias diferentes puedan ser consideradas la misma.

Overriding equals()

Page 7: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Overriding equals()

• Ver ej: OverridingEquals.java

• Análisis:• Declaración válida del método equals()

heredado de Object(): public boolean equals(Object o){ }

Ojo: Los métodos equals(), hashcode() y toString() son todos públicos.

• Asegurarse que el objeto es del tipo correcto (Test Instance of).

Page 8: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

The equals() Contract

• It is reflexive: x.equals(x) should return true.• Is symmetric: x.equals(y) should return true if and

only if y.equals(x) returns true.• Is transitive: if x.equals(y) returns true and

y.equals(z) returns true, then x.equals(z) must return true.

• Is consistent: multiple invocations of x.equals(y) consistently return true or false, provided no information used in equals comparisons on the object is modified.

• For any non-null reference value x, x.equals(null) should return false.

Page 9: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Overriding hashCode()

• Collections como HashMap and HashSet usan el hashcode de un objeto para determinar como debe ser almacenado en la colección, y luego es usado nuevamente para localizar el objeto en la colección.

Page 10: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Overriding hashCode()

• Ver ej: OverridingHashCode.java

• Análisis:• Dos objetos son iguales si tienen el mismo

valor en x, y dos objetos con el mismo valor de x retornan hashcode idénticos. Esto es porque hashcode y equals se basan en la misma variable de isntancia x.

Page 11: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Overriding hashCode()

o public int hashCode() {return name.length(); } o public int hashCode() {return 4; }

• Son ambos legales? Cual será más rápido?

• El primer hashcode será un poco más rápido que el segundo. En general, mientras más unico sea el hashcode, más rápida será la recuperación de los elementos.

Page 12: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

The hashCode() Contract

• Siempre que hashcode() es invocado sobre el mismo objeto, debe retornar consistentemente el mismo entero.

• Si dos objetos son iguales, de acuerdo al método equals(Object), entonces la llamada al método hashCode() sobre cada uno de los dos objetos debe producir el mismo resultado.

• No es requerido que si dos objetos no son iguales de acuerdo al método equals(java.lang.Object), la llamada al método hashCode() debe producir resultados enteros distintos. Sin embargo, el programador debe tener cuidado de producir distintos resultados para objetos iniguales, lo cual podría mejorar el desempeño de hashtables.

Page 13: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

The hashCode() Contract

Page 14: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Collections

Page 15: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Key Interfaces and Classes of the Collections Framework

Las 7 interfaces principales que se deben conocer para el examen:• Collection • Set • SortedSet• List • Map • SortedMap• Queue

Page 16: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Key Interfaces and Classes of the Collections Framework

• Las 13 clases concretas necesarias para el examen:

Collections come in four basic flavors:Lists Lists of things (classes that implement List).Sets Unique things (classes that implement Set).Maps Things with a unique ID (classes that implement Map).Queues Things arranged by the order in which they are to be processed.

Page 17: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Esto es un poco confuso: Existen tres usos cobrecargados de la palabra "collection":

• Collection (lowercase c), representa cualquier estructura de datos, en las cuales objetos son almacenados y sobre las cuales se itera.

• Collection (capital C), java.util.Collection interface de la cual extienden Set, List, and Queue. (extiende, no implementa).

• Collections (capital C and ends with s) es la clase java.util.Collections que almacena un conjunto de métodos estáticos.

Page 18: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

The interface and class hierarchy for collections

Page 19: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Structure of a List, a Set, and a Map

Page 20: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Sorted, Unsorted, Ordered, Unordered• Una implementación de clase (colecciones) puede

ser unsorted and unordered, ordered but unsorted, or ambas ordered and sorted.

• Pero una implementación nunca será sorted but unordered, porque sorted es un tipo específico de ordering.

Page 21: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Ordered

• Cuando una colección está ordenada, significa que se puede iterar através de ésta en un específico (no random) orden.

• Natural order: Para una colección de Strings el natural order es alafabético. Para Integers el natural order es por valor numérico (1,2,3..) y así..

• Para objetos creados no existe natural order; el programdor debe proveerlo através de la interfaz Comparable o la interfaz Comparator, las cuales definen como instancias de una clase puede ser comparadas con otras.

Page 22: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Sorted

• Una colección sorteada es una en la cual el orden está determinado por reglas, conocidad como sort order.

• Un sort order no tiene nada que ver con el orden en que un objeto es añadido o con el acceso a este. Sorting es hecho basado en propiedades de los objetos en sí.

• Al colocar objetos en una coleccion, ésta entiende en que orden debe colocarlo, basado en un sort order.

Page 23: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

List Interface

• List pone atención en los índices. • Tiene métodos relacionados con índices:

get(int index), indexOf(Object o), add(int index, Object obj), etc.

• Las tres implementaciones de List: ArrayList, Vector, LinkedList, están ordenadas por posición del índice

Page 24: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

List Interface: ArrayList, Vector, LinkedList

• ArrayList: Rápida iteración y acceso aleatorio, pero no tan rápido para inserción y borrado. Ordenado (por índice) pero no sorted.

• Vector: basicamente lo mismo que un ArrayList, pero sus métodos son synchronized por thread safety. Usar ArrayList en vez de Vector porque los métodos synchronized añaden un desempeño que podria no ser necesario. Vector es la unica clase (además de ArrayList) que

implementa RandomAccess.

Page 25: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

List Interface: ArrayList, Vector, LinkedList

• LinkedList: elementos son doblemente enlazados unos con otros. Este linkeamiento otorga nuevos métodos para añadir y remover al inicio o final, lo que lo convierte en una elección fácil para la aplicación de una pila o cola.

• Tenga en cuenta que una LinkedList puede iterar más lentamente que un ArrayList, pero es una buena elección cuando usted necesita rápida inserción y borrado.

• A partir de Java 5, LinkedList ha sido mejorado para impelmentar la interfaz java.util.Queue. Soporta métodos comunes de colas: peek(), poll(), and offer().

Page 26: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Set Interface

• Un Set no permite duplicados. Su buen amigo el método equals () permite determinar si dos objetos son idénticos (en cuyo caso sólo uno puede estar en el set).

• Los tres Conjunto implementaciones de Set son:o HashSet, LinkedHashSet, TreeSet

Page 27: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Set Interface: HashSet, LinkedHashSet, TreeSet

• HashSet: unsorted, unordered Set. Usa el hashcode del objeto insertado; mientras más eficiente el hashCode() mejor será el desempeño.

• Use esta clase cuando se quiere una colección

sin duplicados y no importa el orden cuando se itera a través de el.

Page 28: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Set Interface: HashSet, LinkedHashSet, TreeSet

• LinkedHashSet: es una versión ordenada de HashSet que mantiene un List doblemente linkeada a lo largo de todos los elementos.

• Cuando iteras a través de un HashSet el orden es impredecible, mientras un LinkedHashSet te permite iterar a través de los elementos en el orden en el cual ellos fueron insertados.

Page 29: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Set Interface: HashSet, LinkedHashSet, TreeSet

• TreeSet: Es una de las dos colecciones sorted (la otra es TreeMap). Garantiza que los elementos estarán en orden ascendente, de acuerdo al orden natural.

• Opcionalmete se puede definir el otro orden usando Comparable or Comparator.

Page 30: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Map Interface

• Cuida la unicidad de los identificadores. Se mapea un key único a un valor, donde ambos por supuesto son objetos.

• Las clases son:o HashMap, Hashtable, LinkedHashMap, TreeMap

Page 31: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Map Interface: HashMap, Hashtable, LinkedHashMap, TreeMap

• HashMap: unsorted, unordered Map. • Usarlo cuando no se necesita tener cuidado

acerca del orden (durante la iteración).• HashMap permite una clave null y múltiples

valores null en una colección.

• Hashtable: Hashtable es la contraparte sincronizada de HashMap.

• No permite valores ni claves nulas.

Page 32: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Map Interface: HashMap, Hashtable, LinkedHashMap, TreeMap

• LinkedHashMap: mantiene insertion order (or, optionally, access order). Aunque será un poco mas lento que HashMap para añadir y remover elementos, es más rápido para iteración.

• TreeMap: es un sorted Map. Es decir que por default es sorted por el orden natural de los elementos.

Page 33: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Queue Interface

• Está diseñada para almacenar una lista de cosas a ser procesadas de alguna manera.

• Queue tipicamnte son FIFO (first-in, first-out), aunque otros ordenamientos son posibles.

• Soportan todos los métodos estandares de Collections y además añaden métodos propios de las colas.

Page 34: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Queue Interface: PriorityQueue• El propósito de una PriorityQueue es crear una

cola con “prioridad de entrada” y “prioridad de salida”, lo cual es opuesto a una típica cola FIFO.

• Los elementos de una cola de prioridad son ordenados por orden natural (en este caso los elementos sorteados primeros serán accesados primero) o también podría ser de acuerdo a un Comparator.

Page 35: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Collection Interface Concrete Implementation Classes

Page 36: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using the Collections FrameworkSorting Collections• Ver ejemplo TestArrayList.java

The Comparable Interface• La interfaz comparable es usada por los metodos

Collections.sort() y el java.utils.Arrays.sort() para sortear Listas y arreglos respectivamente. o Uso: int x = thisObject.compareTo(anotherObject);

• compareTo() retorna un int bajo las sigtes. Características:o negative If thisObject < anotherObjecto zero If thisObject == anotherObjecto positive If thisObject > anotherObject

Page 37: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

The Comparable Interface

• El método sort() usa el método compareTo() para determinar como un Array o List debe ser sorteado. o Ver ejemplo DVDInfo.java, TestDVD.java

• Solo se puede implementar una sola vez el método compareTo() en una clase, entonces: cómo conseguinmos sortear nuestras clases en un orden diferente al ya especificado?? R. Interfaz Comparator

Page 38: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Sorting with Comparator

• Se puede utilizar la interfaz Comparator para sortear instancias de cualquier clase, aún los que no se pueden modificar.

• Es fácil de implementar, pues tiene un solo método: compare().o Uso:

one.getGenre().compareTo(two.getGenre());o Ver ejemplo: DVDInfo.java, TestDVD.java,

GenreSort

Page 39: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Comparing Comparable to Comparator

Page 40: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Sorting with the Arrays Class

• El método Arrays.sort() es sobresscrito en la misma manera que el método Collections.sort().o Arrays.sort(arrayToSort)o Arra ys.sort(arrayToSort, Comparator)

• El método Arrays.sort(), en caso de primitivos, siempre realiza el sort por orden natural.

• Recordar que los métodos sort() de las clases Collections y Arrays son estaticos, y que alteran los objetos que son sorteados en lugar de retornar un objeto diferente.

• Para sortear un arreglo o colección los elementos deben ser mutuamente

Page 41: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Searching Arrays and Collections• Las búsquedas se realizan con el método

binarySearch(). • Las búsquedas exitosas retornarán el índice del

elemento que es buscado.• Las búsquedas no exitosas retornarán un índice que

representa un punto de inserción.• binarySearch() usa númerso negativos para indicar

puntos de inserción, el primer punto de inserción disponible es -1 Por lo tanto, el punto d einserción actual es representado como (-(insertion point) -1).

• Ej. Si el punto de inserción de una búsqueda fuera el elemento 2, el actual punto de inserción sería -3

Page 42: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• La collection/array debe ser sorteado antes de poder buscar en él.

• Si intentas realizar una búsqueda sobre un collection/array que no ha sido sorted los resultados de la búsqueda serán impredecibles.

• Si la collection/array fue sorteada en natural order, la búsqueda debe ser en natural order.

• Si la collection/array fue sorteada usando un Comparator, la búsqueda debe ser realizada usando el mismo Comparator.

Searching Arrays and Collections

Page 43: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Searching Arrays and Collections• Ver ejemplo: SearchObjArray.java

• Exam Gotchas:• 1. Searching an array or collection that hasn’t

been sorted.• 2. Using a Comparator in either the sort or the

search, but not both.

Page 44: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Converting Arrays to Lists to Arrays• Las clses List y Set tienen el método toArray(),

y la clase Arrays tiene un método llamado asList().

• El método Arrays.asList() copia un arreglo dentro d eun lista.

• Cuando usas el método asList(), si actualizas el array o la lista, ambos se actualizan automáticamente.

• Ver ejemplo: ArraysToList.java

Page 45: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using Lists

• Métodos iteradores:• boolean hasNext() : retorna verdadero si

existe al menos un elemento más en la colección que está siendo recorrida. La invocación a hasNext() no te mueve al sigte. Elemento.

• object next() : retorna el siguiente elemento en la colección, y te mueve al elemento siguiente.

Ver ejemplo: Dog.java

Page 46: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using Sets

• Si intenta añadir un elemento existente en un set, el elemento no será añadido y el método add() retornará falso.

Ver ejmplo: SetTest.java Es importante saber que el orden de impresión de

los objetos en el segundo lazo no es predecible. HashSets y LinkedHashSets no garantizan ningún ordenamiento.

Con respecto a TreeSet se debe recordar que es un Set cuyos elementos están sorteados, por lo tanto sus elementos deben ser mutuamente comparablea.

Page 47: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using Maps

• Cualqueir clase que sea usada como key debe sobreescribir los métodos hashCode() y equals().

• Ver ejemplo: MapTest.java• La quinta salida es null. El método get() falla en

encontrar el objeto Cat que fue insertado. Pero por qué cuando se usa una instancia de Dog como key si funciona?? Esto es porque Dog sobreescribe los métodos equals() y hashcode().

Page 48: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using the PriorityQueue Class

• Al contrario de una estructura básica de cola (FIFO), una PriorityQueue ordena sus elementos uasando una prioridad definida por el usuario.

• La prioridad puede ser simple como natural order.

• Además una PriorityQueue puede ser ordenada usando Comparator, el cual premite definir el orden que se requiera.

Page 49: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Using the PriorityQueue Class

• Queues tienen método no encontrados en otras colecciones:

• Offer() añade elementos.• peek() retorna el elemento de más alta priridad

en la cola sin removerlo.• poll() returns retorna el elemento de más alta

priridad en la cola y lo remueve.

o Ver ejemplo: PQ.java

Page 50: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Method Overview for Arrays and Collections

Page 51: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Method Overview for List, Set, Map, and Queue

Page 52: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.
Page 53: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generic Types

Page 54: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• List myList = new ArrayList(); // can't declare a type• myList.add("Fred"); // OK, it will hold Strings• myList.add(new Dog()); // and it will hold Dogs too• myList.add(new Integer(42)); // and Integers…

Una colección no-genérica puede almacenar cualquier tipo de Objetos (no primitivos).

Page 55: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Genericos prestan atención y cuidado en el tipo de datos durante las operaciones de añadir y sacar elementos de las colecciones.

• List<String> myList = new ArrayList<String>(); myList.add("Fred"); // OK, it will hold Strings myList.add(new Dog()); // compiler error!!

o String s = (String)myList.get(0); // pre-genericso String s = myList.get(0); //wit-generics

Page 56: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

o for (String s : myList) { int x = s.length(); }

o void takeListOfStrings(List<String> strings) { strings.add("foo"); // no problem adding a String }

o void takeListOfStrings(List<String> strings) { strings.add(new Integer(42)); // NO!! strings is type

safe }

Page 57: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• List<Object> myList = new ArrayList<Object>();

• Declarar una Lista con un tipo de parametro <Object> hace que la coleccion trabaje casi en el mismo modo que una coleccion no-generica (pre-java5), se puede colocar cualquier tipo de objeto en la colección.

Page 58: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generics and Legacy Code

A pre-Java 5 List meant to hold only Integers: List myList = new ArrayList(); becomes List<Integer> myList = new ArrayList<Integer>();

and a list meant to hold only Strings goes from public List changeStrings(ArrayList s) { } to this: public List<String> changeStrings(ArrayList<String>

s) { }

Page 59: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Mixing Generic and Non-generic Collections

• Ver ejemplo: TestLegacy.java, Adder.java

• Es legal combinar código genérico con código no-genérico.

• En la clase Adder, el método addAll() asume/espera que la lista pasada este restringida solo a Integers, pero esto no está garantizado.

Page 60: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Ver ejemplo: TestLegacy.java -> método insert2()

• El compilador no sabe si el método insert() está añadiendo el tipo correcto o incorrecto.

• La razón por la cual el compilador produce un warning es porque el método está añadiendo algo a la calección. En otras palabras el compilador solo sabe que existe la posibilidad de que se añada algo incorrecto.

Page 61: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Para la declaración: List<Integer> myList = new ArrayList<Integer>();

• La JVM ve lo que siempre vio: List myList = new ArrayList();• El compilador siempre inserta el cast (el cast que dberiamos hacer

si usaramos colecciones pre-java 5).

• Piensa en genéricos estrictamente como una protección en tiempo de compilación. Pero ninguna de estas protecciones existen en runtime.

• Usando genéricos es una protección en tiempo de compilación que garantiza que no insertes cosas erradas dentro de una colección, y elimina la necesidad de hacer cast cuando tomamos objetos de la colección.

Page 62: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Unboxingo List test = new ArrayList();o test.add(43);o int x = (Integer)test.get(0); // you must cast !!

o List<Integer> test2 = new ArrayList<Integer>();o test2.add(343);o int x2 = test2.get(0); // cast not necessary

Page 63: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Polymorphism and Generics

• class Parent { }• class Child extends Parent { }• List<Parent> myList = new ArrayList<Child>();

• It Work??• NO, existe una regla simple ---- el tipo de la variable

de declaración debe concordar con el tipo que se le pasa al actual tipo de objeto.

o List<Animal> aList = new ArrayList<Animal>(); // yeso List<Animal> aList = new ArrayList<Dog>(); // no

Page 64: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Polymorphism and Generics

• this is NOT how it works with arrays, import java.util.*; class Parent { } class Child extends Parent { } public class TestPoly { public static void main(String[] args) { Parent[] myArray = new Child[3]; // si permite

polimorfismo }}

Page 65: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Polymorphism and Generics

• Polimorfismo en colecciones con genéricos solo puede ser aplicada en el "base" type (el tipo de clase colección).

• Ej.o List<JButton> myList = new ArrayList<JButton>();o Set<Animal> mySet = new HashSet<Animal>();

Page 66: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generic Methods

o Ver ejemplo: AnimalDoctor.java

o Ver ejemplo: AnimalDoctorGeneric.java

El compilador muestra los errores, pues simplemente no se puede asignar los ArrayLists de sustipos de Animal (<Dog>, <Cat>, or <Bird>) a un ArrayList del supertipo <Animal>.

Page 67: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generic Methods

public void foo() { Cat[] cats = {new Cat(), new Cat()}; addAnimal(cats); // no problem, send the Cat[] to the method } public void addAnimal(Animal[] animals) { animals[0] = new Dog(); // Eeek! We just put a Dog // in a Cat array! }

• Este es el escenario que se busca prevenir…..asi sea un Array o un ArrayList. La diferencia es que el compilador te permite hacer esto con Arrays pero no con colecciones genéricas.

Page 68: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generic Methods

• La razón por la cual este tipo d eproblema no aparece en compilación es porque está definido como una runtime exception (ArrayStoreException).

• Si intentas añadir un Cat a un objeto que actualemente es un Array de Dog, se obtenrdrá está excepcion.

• Es decir, en runtime la JVM conoce los tipos en los arrays, pero no el tipo de una colección.

Page 69: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

public void addAnimal(List<Animal> animals) { animals.add(new Dog()); // still OK as always

} public static void main(String[] args) {

List<Dog> animals = new ArrayList<Dog>(); animals.add(new Dog()); animals.add(new Dog()); AnimalDoctorGeneric doc = new AnimalDoctorGeneric();

doc.addAnimal(animals); // THIS is where it breaks! }

• El problema está en el método add(). Necesitamos una menera de decirle al compilador que prometemos no añadir nada a la colección.

Page 70: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

WildCard syntax <?>

• Permite a los métodos genéricos, aceptar subtipos (o supertipos) del tipo declarado en el argumento del método:

void addD(List<Dog> d) {} // can take only <Dog>

void addD(List<? extends Dog>) {} // take a <Dog> or <Beagle>

Page 71: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

WildCard syntax <?>

• El keyword extends en el contexto de wildcard representa subclasses (o superclases) e implementaciones d einterfaces.

• No existe la sintaxis <? implements Serializable>. Sino: void foo(List<? extends Serializable> list)

• Cuando se utiliza un wildcard, List<? extends Dog>, la colecciónpuede ser accesada pero no modificada.

• Cuando usas un wildcard, List<?>, cualquier tipo generico puede ser asignado a la referencia, pero solo para acceso y no modificación.

Page 72: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

WildCard syntax <?>

• the keyword super. public void addAnimal(List<? super Dog> animals) { animals.add(new Dog()); // adding is sometimes OK with super } public static void main(String[] args) { List<Animal> animals = new ArrayList<Animal>(); animals.add(new Dog()); animals.add(new Dog()); AnimalDoctorGeneric doc = new AnimalDoctorGeneric(); doc.addAnimal(animals); // passing an Animal List }

• Esto esencialmente le dice al compilador que acepte una Lista con tipos genérios, los cuales pueden ser de tipo Dog, o un supertipo de Dog. Nada más abajo en el arbol de herencia será permitido pero si cualquier cosa que está más arriba de Dog.

Page 73: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

WildCard syntax <?>

• public void foo(List<?> list) { }• public void foo(List<Object> list) { }

• Son iguales?? • No, List<?>, donde el wildcard wildcard <?> sin el keyword

extends or super, significa "any type.“

• List<Object> es completamente diferente de List<?>. • List<Object> significa que el método puede solo tomar una

lista de Objetcs.

• Pero, List<? extends Object> and List<?> son absolutamente idénticos.

Page 74: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

WildCard syntax <?>

• Cuáles compilarán???o 1) List<?> list = new ArrayList<Dog>();o 2) List<? extends Animal> aList = new

ArrayList<Dog>();o 3) List<?> foo = new ArrayList<? extends Animal>();o 4) List<? extends Dog> cList = new

ArrayList<Integer>();o 5) List<? super Dog> bList = new

ArrayList<Animal>();o 6) List<? super Animal> dList = new

ArrayList<Dog>();

• 1, 2, and 5.

Page 75: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Generic Declarations

• Making Your Own Generic Class• public interface List<E>• The <E> is a placeholder for the type you pass in. The List interface is

behaving• as a generic "template" (sort of like C++ templates), and when you write

your code,• you change it from a generic List to a List<Dog> or List<Integer>, and so

on.• The E, by the way, is only a convention. Any valid Java identifier would

work• here, but E stands for "Element," and it's used when the template is a

collection. The• other main convention is T (stands for "type"), used for, well, things that are

NOT collections.

boolean add(E o)• In other words, whatever E is when you declare the List, that's what you

can add to• it.

Page 76: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Declaration conventions for generics use T for type and E for element:

• public interface List<E> // API declaration for List• boolean add(E o) // List.add() declaration• q The generics type identifier can be used in class, method,

and variable• declarations:• class Foo<t> { } // a class• T anInstance; // an instance variable• Foo(T aRef) {} // a constructor argument• void bar(T aRef) {} // a method argument• T baz() {} // a return type• The compiler will substitute the actual type.

Page 77: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Making Your Own Generic Class• Ver ejemplo: CarRental.java

• You really don't want to make separate subclasses for every possible kind of

• rentable thing (cars, computers, bowling shoes, children, and so on).

• you can make the Rental class a generic type—a template for any

• kind of Rentable thing—and you're good to go

Page 78: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• Ver ejemplo TestRental.java• Ver ejemplo UseTwo.java

Page 79: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

Creating Generic Methods

• But it's possible to define a• parameterized type at a more granular level—a

method.• Imagine you want to create a method that takes an

instance of any type,• instantiates an ArrayList of that type, and adds the

instance to the ArrayList.• Using a• generic method, we can declare the method without a

specific type and then get the• type information based on the type of the object

passed to the method.

Page 80: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

public class CreateAnArrayList { public <T> void makeArrayList(T t) { // take an object of an // unknown type and use a // "T" to represent the type List<T> list = new ArrayList<T>(); // now we can create the // list using "T" list.add(t); }}

• if you invoke the makeArrayList() method with a Dog

• instance, the method will behave as though it looked like this all along:

public void makeArrayList(Dog t) { List<Dog> list = new ArrayList<Dog>(); list.add(t); }

Page 81: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• The strangest thing about generic methods is that you must declare the type

• variable BEFORE the return type of the method:• public <T> void makeArrayList(T t)• The <T> before void simply defines what T is before you use it as a type in

the• argument. You MUST declare the type like that unless the type is specified

for the• class. In CreateAnArrayList, the class is not generic, so there's no type

parameter• placeholder we can use.• You're also free to put boundaries on the type you declare, for example if

you want• to restrict the makeArrayList() method to only Number or its subtypes

(Integer,• Float, and so on) you would say• public <T extends Number> void makeArrayList(T t)

Page 82: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• You can declare a generic method using a type not defined in the class:

• public <T> void makeList(T t) { }• is NOT using T as the return type. This method

has a void return type, but• to use T within the method's argument you

must declare the <T>, which• happens before the return type.

Page 83: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• It’s tempting to forget that the method argument is NOT where you• declare the type parameter variable T. In order to use a type variable

like T, you must• have declared it either as the class parameter type or in the method,

before the return• type. The following might look right,• public void makeList(T t) { }• But the only way for this to be legal is if there is actually a class• named T, in which case the argument is like any other type

declaration for a variable.• And what about constructor arguments? They, too, can be declared

with a generic type,• but then it looks even stranger since constructors have no return type

at all:• public class Radio {• public <T> Radio(T t) { } // legal constructor• }

Page 84: SUN CERTIFIED JAVA PROGRAMMER (SCJP) CAPÍTULO 7: COLECCIONES Y GENÉRICOS.

• classes or methods is to use a <?> in the wildcard syntax rather than a type

• variable <T>, <E>, and so on. This code might look right, but isn’t:

• public class NumberHolder<? extends Number> { }• While the question mark works when declaring a reference

for a variable,• it does NOT work for generic class and method

declarations. This code is not legal:• public class NumberHolder<?> { ? aNum; } // NO!• But if you replace the <?> with a legal identifier, you’re

good:• public class NumberHolder<T> { T aNum; } // Yes