scjp, clase 6: collections

66
SCJP 6 Clase 6 – Collections e introducción a generics Ezequiel Aranda Sun Microsystems Campus Ambassador

Upload: flekoso

Post on 22-May-2015

7.398 views

Category:

Technology


3 download

DESCRIPTION

Slides de la sexta clase del curso de Java SCJP dictado en la Universidad Nacional de Centro de La Provincia de Buenos Aires.Contenido:1. Collections

TRANSCRIPT

Page 1: SCJP, Clase 6: Collections

SCJP 6 Clase 6 – Collections e

introducción a generics

Ezequiel Aranda

Sun Microsystems Campus Ambassador

Page 2: SCJP, Clase 6: Collections

Disclaimer & Acknowledgments

> Even though Ezequiel Aranda is a full-time employee of Sun Microsystems, the contents here are created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems.

> Sun Microsystems is not responsible for any inaccuracies in the contents.

> Acknowledgments – The slides of this presentation are made from “SCJP Unit 6” by Warit Wanwithu and Thanisa Kruawaisayawan and SCJP Workshop by P. Srikanth.

> This slides are Licensed under a Creative Commons Attribution – Noncommercial – Share Alike 3.0 > http://creativecommons.org/licenses/by-nc-sa/3.0/

Page 3: SCJP, Clase 6: Collections

AGENDA

> Object > toString

> equals

> hashCode

> Collections > List

> Set

> Map

> Queue

> Ordenamiento > Comparable

> Comparator

Page 4: SCJP, Clase 6: Collections

Métodos de la clase Object

> int hashcode()

> boolean equals (Object obj)

> String toString()

> void finalize()

> final void notify()

> final void notifyAll ()

> final void wait()

Page 5: SCJP, Clase 6: Collections

Sobrescribir toString()

> Al pasar una referencia a un objeto como parámetro al método toString(),el método toString de dicho objeto es llamado.

> Si ejecutamos algo como: HardToRead h = new HardToRead() System.out.println(h);

> Obtendremos algo como: HardToRead@a47e0

Page 6: SCJP, Clase 6: Collections

class Bob { int shoeSize; String nickName; Bob(String nickName, int shoeSize) { this.shoeSize = shoeSize; this.nickName = nickName; } public String toString() { return ("I am a Bob, but you can call me " + nickName +". My shoe size is " + shoeSize);

} } // Pregunta // Bob f = new Bob("GoBobGo", 19); // System.out.println(f);

Page 7: SCJP, Clase 6: Collections

Sobreescribir equals() public class EqualsTest { public static void main (String [] args) { Metre one = new Metre(8); Metre two = new Metre(8); if (one.equals(two)) System.out.println("one and two are equal"); } } class Metre { private int value; Metre(int val) { value = val; } } // ¿“One” es igual a “two”?

Page 8: SCJP, Clase 6: Collections

class Metre { private int value; Metre(int val) {value = val;} public int getValue() { return value; } public boolean equals(Object o) { if ((o instanceof Metre) && (((Metre)o).getValue() == this.value)) {

return true; } else { return false; } }

}

Page 9: SCJP, Clase 6: Collections

Sobrescribir hashCode()

> Si bien puede pensarse que es un identificador de objetos, no necesariamente es único.

> Debemos saber cuales collections lo utilizan (son las que tienen el prefijo “hash” en el nombre, así que no debería ser particularmente difícil).

> También debemos poder reconocer las implementaciones apropiadas de hashCode().

Page 10: SCJP, Clase 6: Collections

Ejemplo de hashcode

Page 11: SCJP, Clase 6: Collections

Entendiendo hashCode()

> Si dos objetos son iguales, sus hashcodes deben ser iguales.

> Pero si dos objetos tienen el mismo hashcode, no necesariamente son iguales.

> En el examen no se evalúa que sepamos rankear las eficiencias de distintos hashcodes.

> Pero debemos saber cuales funcionarán y cuales no (es decir, cuales nos permitirán encontrar un objeto en la colección)

Page 12: SCJP, Clase 6: Collections

class SaveMe implements Serializable { transient int x; int y; SaveMe(int xVal, int yVal) { x = xVal; y = yVal; } public int hashCode() { return (x ^ y); } public boolean equals(Object o) { SaveMe test = (SaveMe)o; if (test.y == y && test.x == x) { return true; } else { return false; } } }

Page 13: SCJP, Clase 6: Collections

Implementando hashCode()

> La variable transient volverá (luego de serializar el objeto) con un valor por defecto, en vez del valor que tenía la variable al momento de guardarla.

> En conclusión: las variables transient pueden dar problemas en las implementaciones de equals() y hashCode().

Page 14: SCJP, Clase 6: Collections

Contratos

> En Java, un contrato es un conjunto de reglas que deberían ser seguidas si queremos que nuestras implementaciones funcionen de la forma esperada.

> En otras palabras, si no seguimos los contratos, nuestro código posiblemente compile y corra, pero podría fallar inesperadamente en su ejecución.

Page 15: SCJP, Clase 6: Collections

El contrato de equals

> Es reflexivo. Para cualquier referencia por ejemplo x, x.equals(x) debería devolver true.

> Es simétrico. Para cualquier par de referencias, por ejemplo x e y, si x.equals(y) es true si y solo si y.equals(x) devuelve true.

> Es transitivo. Para cualquier conjunto de referencias, por ejemplo 'x', 'y' y 'z', si x.equals(y) devuelve true y para y.equals(z) devuelve true, entonces z.equals(x) debe devolver true.

Page 16: SCJP, Clase 6: Collections

El contrato de equals (II)

> Es consistente. Para cualquier pareja de referencias, por ejemplo x e y, hacer x.equals(y) consistentemente devuelve true o consistentemente devuelve false, ninguna información usada en comparaciones equals modifican al objeto.

> Para cualquier referencia no nula, por ejemplo x, x.equals(null) debe devolver false.

> Adicionalmente, equals y hashCode están unidos por un contrato conjunto que dice que si dos objetos son “equals”, deben tener hashCodes idénticos.

Page 17: SCJP, Clase 6: Collections

El contrato de hashCode

> Siempre que es invocado con el mismo objeto más de una vez durante la ejecución de una aplicación Java, el hashCode () debe devolver constantemente el mismo número entero, siempre y cuando la información utilizada para las comparaciones equals() no modifiquen el objeto. Este entero no es necesario que mantenga la coherencia de la ejecución en una aplicación a otra ejecución de la misma aplicación.

Page 18: SCJP, Clase 6: Collections

El contrato de hashCode (II)

> Si dos objetos son iguales de acuerdo con el método equals(java.lang.Object), entonces se pide que el método hashCode() en cada uno de los dos objetos debe devolver el mismo resultado entero.

> No es necesario que si dos objetos son desiguales en función del método equals(Java.lang.Object), entonces se pide que hashCode () en cada uno de los dos objetos debe devolver como resultado dos enteros distintos. Sin embargo, el programador debe ser consciente de que la producción de distintos resultados enteros para los objetos puede mejorar el rendimiento de tablas hash.

Page 19: SCJP, Clase 6: Collections

El contrato de hashCode (III)

> Debemos recordar lo siguiente:

Condición Requisito Permitido (aunque no requerido)

x.equals(y) == true x.hashCode() == y.hashCode()

x.hashCode() == y.hashCode()

x.equals(y) == true

x.equals(y) == false

Sin requerimientos de hashCode().

x.hashCode() != y.hashCode()

x.equals(y) == false

Page 20: SCJP, Clase 6: Collections

1. public class Test

2. {

3. private int num;

4. private String data;

5. public boolean equals(Object obj)

6. {

7. if(this == obj)

8. return true;

9. if((obj == null) || (obj.getClass() != this.getClass()))

10. return false;

11. // A esta altura, obj es de tipo Test

12. Test test = (Test)obj;

13. return num == test.num &&

14. (data == test.data || (data != null && data.equals(test.data)));

15. }

Page 21: SCJP, Clase 6: Collections

17. public int hashCode()

18. {

19. int hash = 7;

20. hash = 31 * hash + num;

21. hash = 31 * hash + (null == data ? 0 : data.hashCode());

22. return hash;

23. }

24.

25. // otros métodos

26. }

Page 22: SCJP, Clase 6: Collections

Collections

> El API “comienza” con la definición de varias interfaces, de las cuales debemos conocer las siguientes para el examen: > Collection

> List

> Queue

> Set

> Map

> SortedSet

> SortedMap

Page 23: SCJP, Clase 6: Collections

Collections (II)

> Hay un gran número de clases concretas, para el examen alcanzará con conocer las siguientes 13:

Maps Sets Lists Queues Utilities

HashMap  HashSet  ArrayList  PriorityQueue  Collections

Hashtable  LinkedHashSet  Vector  Arrays

TreeMap  TreeSet  LinkedSet 

LinkedHashMap 

Page 24: SCJP, Clase 6: Collections

La palabra “collection”

> Es fácil confundir “Collection” con “Collections”, y viceversa.

> Collections es una clase, con métodos utilitarios.

> Mientras que Collection es una interfaz con declaraciones de métodos comunes a la mayoría de las colecciones, incluyendo add(), remove(), contains(), size() e iterator().

Page 25: SCJP, Clase 6: Collections

La palabra “collection” (II)

> collection (‘c’ minúscula), representa una de las estructuras de datos en las cuales se almacenan los objetos para luego iterar sobre ellos.

> Collection (‘C’ mayúscula), es la interfaz java.util.Collection, la cual extienden Set, List y Queue (no existen implementaciones directas de Collection).

> Collections (‘C’ mayúscula, termina en ‘s’), es la clase java.util.Collections, que contiene gran cantidad de métodos estáticos para utilizar en colecciones.

Page 26: SCJP, Clase 6: Collections
Page 27: SCJP, Clase 6: Collections

Colecciones

> Lists, listas de cosas (implementan List).

> Sets, conjuntos de cosas de cardinalidad 1 (implementan Set).

> Maps, cosas con IDs únicos (implementan Map)

> Queues, cosas ordenadas en la forma en que serán procesadas.

Page 28: SCJP, Clase 6: Collections

Comparación entre List, Set y Map

Page 29: SCJP, Clase 6: Collections

“Ordenada”

> Cuando una colección está ordenada, significa que podemos recorrer sus elementos en un orden especifico.

> Una Hashtable, no está ordenada.

> Un ArrayList es exactamente como un array.

> Nunca podremos llamar al método “sort” en una colección no ordenada.

Page 30: SCJP, Clase 6: Collections

Sorted

> Significa que el orden de una colección esta establecido por una regla. > Una regla para ordenar un conjunto de palabras

podría ser colocarlas en orden alfabético.

> Para números enteros, podríamos ordenar de mayor a menor de acuerdo a su valor.

> ¿Y como podemos hacer con objetos? No hay una regla para la clase Foo, salvo que el desarrollador de esa clase provea una, utilizando la interfaz Comparable.

Page 31: SCJP, Clase 6: Collections

Interfaz List

> Las listas tienen índices.

> De hecho, la única cosa que diferencia a algo que es una List de algo que no lo es, es un conjunto de métodos relacionados con el índice (por ej.: get(int index), indexOf(Object o), add(int index, Object obj))

> Las tres implementaciones de List están ordenadas por el valor del índice.

Page 32: SCJP, Clase 6: Collections

ArrayList

> La forma de ver esta implementación es que es un array que puede crecer.

> Esta ordenada, pero no es “sorted” (sólo está ordenada por el índice).

> Se utiliza cuando necesitamos iterar rápidamente, pero no necesitamos agregar o borrar elementos.

Page 33: SCJP, Clase 6: Collections

Vector

> Un vector es básicamente lo mismo que un ArrayList, pero sus métodos están sincronizados.

> En general, es preferible utilizar ArrayList en vez de Vector, dado que los métodos sincronizados reducen la performance de nuestro programa.

> Vector y ArrayList son las únicas clase que implementan RandomAccess.

Page 34: SCJP, Clase 6: Collections

LinkedList

> Está ordenada por el índice, pero a diferencia de ArrayList, los elementos están doblemente vinculados.

> LinkedList itera más lento que un ArrayList, pero las inserciones y los borrados son más rápidos.

> Soporta los métodos peek(), poll() y offer() (a partir de Java 5, porque implementa Queue).

Page 35: SCJP, Clase 6: Collections

Interfaz Set

> Un Set no permite duplicados.

> Se utiliza equals() para determinar si dos objetos son identicos.

Page 36: SCJP, Clase 6: Collections

HashSet

> No esta orden, ni utiliza una regla de ordenamiento.

> Utiliza el hashcode del elemento para localizarlo. Cuanto mejor la implementación, mejor performance en el acceso.

> Se utiliza cuando el único requisito es no tener duplicados y no importa el orden al iterarlo.

Page 37: SCJP, Clase 6: Collections

LinkedHashSet

> Es una versión ordenada de HashSet.

> Mantiene una lista doblemente vinculada de los elementos.

> El orden de iteración se corresponde con el de inserción de los elementos.

Page 38: SCJP, Clase 6: Collections

TreeSet

> Junto con TreeMap, son las únicas colecciones con regla de ordenamiento.

> Por defecto, usa el orden natural, pero tiene un constructor que permite establecer la regla de ordenamiento.

> Usa una estructura de árbol Red-Black que asegura que los elementos se encuentren en orden ascendente.

Page 39: SCJP, Clase 6: Collections

Interfaz Map

> Un mapa posee identificadores únicos.

> Se mapea una clave única (ID) a un valor especifico. Ambos, clave y valor, son objetos.

> Las implementaciones de Map permiten buscar un valor dada la clave.

Page 40: SCJP, Clase 6: Collections

HashMap

> HashMap es una colección sin orden ni regla de ordenamiento.

> Se utiliza cuando no nos importa el orden al iterar sobre los elementos, sino encontrar siempre el valor dada la clave.

> Permite un null en la claves, y múltiples nulls entre los valores de la colección.

Page 41: SCJP, Clase 6: Collections

Hashtable

> Es la versión sincronizada de HashMap.

> Al igual que el Vector, conviene utilizarlo solo cuando es necesario que los métodos sean sincronizados, de otra forma, estaremos reduciendo la performance de nuestro programa en forma innecesaria.

> Un Hashtable no acepta ningún null.

Page 42: SCJP, Clase 6: Collections

LinkedHashMap

> Mantiene el orden de inserción.

> Esto hace que sea algo más lento que HashMap para agregar y remover elementos.

> Sin embargo, la iteración a través de los elementos es más rápida.

Page 43: SCJP, Clase 6: Collections

TreeMap

> Permite establecer un orden de los elementos utilizando Comparator o Comparable.

Page 44: SCJP, Clase 6: Collections

Interfaz Queue

> Un Queue está diseñado para contener una lista de to-dos o cosas que deben procesarse de alguna forma.

> Si bien es posible darle otros ordenamientos, en general se piensa en un queue como un FIFO (first in, first out).

> Soportan todos los métodos estándar de las colecciones y añaden métodos para agregar y quitar elementos y evaluar los elementos del queue.

Page 45: SCJP, Clase 6: Collections

PriorityQueue

> Incluida en Java 5.

> Su propósito es crear una cola ordenada por prioridad en vez de utilizar el enfoque FIFO.

> Sus elementos se ordenan con una regla de ordenamiento.

Page 46: SCJP, Clase 6: Collections

Resumen

Page 47: SCJP, Clase 6: Collections

ArrayList

> Crece dinámicamente.

> Provee mejores mecanismos de inserción y búsquedas que los arrays. List myList = new ArrayList();

> A partir de Java 5, podemos utilizar genéricos: List<String> myList = new ArrayList<String>();

Page 48: SCJP, Clase 6: Collections

ArrayList (II)

> ArrayList<String> es similar en muchas formas a String[].

> Sin embargo, ArrayList<String> es más versátil.

> Por ejemplo: List<String> list = new ArrayList<String>();

String[] list = new String[xxx]; //xxx debe ser un valor específico

Page 49: SCJP, Clase 6: Collections

Autoboxing en colecciones

> En general, las colecciones no pueden contener tipos primitivos. myInts.add(new Integer(42)); // pre Java 5.0

> A partir de Java 5, los tipos primitivos deben convertirse a objetos equivalentes (utilizando sus respectivos wrappers). Sin embargo, el autoboxing realiza esta conversión automáticamente. myInts.add(42); // Java 5.0

Page 50: SCJP, Clase 6: Collections

Ordenando Colecciones

ArrayList<String> stuff = new ArrayList<String>();

stuff.add("Denver"); stuff.add("Boulder"); stuff.add("Vail"); stuff.add("Aspen"); stuff.add("Telluride"); System.out.println("unsorted " + stuff); Collections.sort(stuff); System.out.println("sorted " + stuff);

Page 51: SCJP, Clase 6: Collections

Ordenando Colecciones (II)

> ¿Podemos hacer esto? ArrayList<DVDInfo> dvdList = new ArrayList<DVDInfo>();

Collections.sort(dvdList);

> Sí, dado que sort() toma como argumento una lista.

> Sin embargo, sólo funcionará cuando los elementos de la lista implementen Comparable.

Page 52: SCJP, Clase 6: Collections

Forma de implementar Comparable

class DVDInfo implements Comparable<DVDInfo> { // #1

public int compareTo(DVDInfo d) { return title.compareTo(d.getTitle()); // #2

} }

> #1: implementamos Comparable de tal forma que un objeto DVDInfo se compare con otros objetos DVDInfo.

> #2 Implementamos el método compareTo.

Page 53: SCJP, Clase 6: Collections

Comparable

class DVDInfo implements Comparable<DVDInfo> {

public int compareTo(DVDInfo d) { return title.compareTo( d.getTitle() ); } }

> Negativo si thisObject < anotherObject

> Cero si thisObject == anotherObject

> Positivo si thisObject > anotherObject

Page 54: SCJP, Clase 6: Collections

Comparable (II)

> Es importante recordar que cuando sobrescribimos equals(), debemos tomar un argumento de tipo Object.

> Sin embargo, cuando sobrescribimos compareTo(), debemos tomar un argumento del tipo que estamos ordenando.

Page 55: SCJP, Clase 6: Collections

Ordenando con Comparator

> A diferencia de Comparable, un Comparator no fuerza la modificación de la clase que queremos oredenar.

import java.util.*; class GenreSort implements Comparator<DVDInfo> {

public int compare(DVDInfo one, DVDInfo two) {

return one.getGenre().compareTo(two.getGenre());

} }

Page 56: SCJP, Clase 6: Collections

Comparable Vs. Comparator

java.lang.Comparable java.util.Comparator

int objOne.compareTo(objTwo) int compare(objOne, objTwo)

Retorna NegaGvo si objOne < objTwo      Cero si objOne == objTwo     PosiGvo si  objOne > objTwo

Lo mismo que Comparable

Hay que modificar la clase cuyas instancias queremos ordenar

Se construye una clase separada de aquella cuyas instancias queremos

ordenar.

Solo puede crearse una secuencia de ordenamiento

Varias secuencias pueden crearse

Implementada en las APIs de Java frecuentemente (String, Wrappers, Date,

Calendar)

Pensado para ser implementado en ordenamientos creados por terceros

Page 57: SCJP, Clase 6: Collections

Usando Listas

> hasNext() retorna true si hay al menos un elemento mas en la colección que estamos recorriendo. > Invocar hasNext no nos posiciona en el elemento

siguiente.

> next() retorna el siguiente elemento en la colección. > Invocar next nos posiciona el elemento que se

encuentra a continuación del que acabamos de retornar.

Page 58: SCJP, Clase 6: Collections

Usando Listas (II)

Iterator<Dog> i3 = d.iterator(); // creamos un iterador para “Dog” while (i3.hasNext()) { Dog d2 = i3.next(); // no requiere cast System.out.println(d2.name); } // O podemos hacer: Iterator i3 = d.iterator(); Dog d2 = (Dog)i3.next();

Page 59: SCJP, Clase 6: Collections

Usando Sets

> Recuerden que los Sets son sin duplicados. boolean[] ba = new boolean[5] //definición de s ba[0] = s.add(”homer"); ba[1] = s.add(new Integer(42)); ba[2] = s.add("bart"); ba[3] = s.add(”homer"); ba[4] = s.add(new Object());

Page 60: SCJP, Clase 6: Collections

Usando Sets (II)

> Set s = new HashSet(); > true true true false true

> homer java.lang.Object@e09713 42 bart

> Set s = new TreeSet(); > Exception in thread "main"

java.lang.ClassCastException: java.lang.String

Page 61: SCJP, Clase 6: Collections

Usando Sets (III)

> El orden de los objetos impresos no es predecible. HashSet y LinkedHashSet no garantizan ningún orden.

> La cuarta invocación falla, puesto que intentamos agregar un elemento que ya era parte del conjunto.

> ¿Por qué aparece la excepción?

Page 62: SCJP, Clase 6: Collections

Usando Maps

Map<Object, Object> m = new HashMap<Object,Object>();

m.put("k1", new Dog("aiko"));

// agregamos pares clave/ valor

m.put("k2", Pets.DOG);

m.put(Pets.CAT, "CAT key");

Dog d1 = new Dog("clover");

m.put(d1, "Dog key");

m.put(new Cat(), "Cat key");

Page 63: SCJP, Clase 6: Collections

Usando PriorityQueue

> PriorityQueue, a diferencia de las estructuras FIFO, ordena sus elementos utilizando una regla de ordenamiento definida por el usuario.

> Un PriorityQueue puede ordenarse utilizando un Comparator, que nos permite definir el ordenamiento como deseemos.

> Las Queues tienen métodos que no se encuentran en otras subinterfaces de Collection: peek, poll y offer.

Page 64: SCJP, Clase 6: Collections

Usando PriorityQueue (II)

int[] ia = {1,5,3,7,6,9,8 }; PriorityQueue<Integer> pq1 = new PriorityQueue<Integer>();

for(int x : ia) pq1.offer(x); for(int x : ia) System.out.print(pq1.poll() + " ");

> offer() agrega elementos.

> peek() retorna el elemento de mayor prioridad sin removerlo de la colección.

> poll() retorna el elemento de mayor prioridad en la colección, y lo remueve de la misma.

Page 65: SCJP, Clase 6: Collections

Pregunta

String[] sa = {">ff<", "> f<", ">f <", ">FF<" };

PriorityQueue<String> pq3 = new PriorityQueue<String>();

for(String s : sa) pq3.offer(s); for(String s : sa) System.out.print(pq3.poll() + " ");

> ¿Cuál es el resultado?

Page 66: SCJP, Clase 6: Collections

Preguntas