Sei sulla pagina 1di 66

SCJP 6

Clase 6 Collections e
introduccin a generics

Ezequiel Aranda
Sun Microsystems Campus
Ambassador

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/

AGENDA
>Object
>toString
>equals
>hashCode

>Collections
>List
>Set
>Map
>Queue

>Ordenamiento
>Comparable
>Comparator

Mtodos de la clase Object


>int hashcode()
>boolean equals (Object obj)
>String toString()
>void finalize()
>final void notify()
>final void notifyAll ()
>final void wait()

Sobrescribir toString()
>Al pasar una referencia a un objeto como
parmetro al mtodo toString(),el mtodo
toString de dicho objeto es llamado.
>Si ejecutamos algo como:
HardToRead h = new HardToRead()
System.out.println(h);

>Obtendremos algo como:


HardToRead@a47e0

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);

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?

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; }
}
}

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 debera ser
particularmente difcil).
>Tambin debemos poder reconocer las
implementaciones apropiadas de hashCode().

Ejemplo de hashcode

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 evala que sepamos
rankear las eficiencias de distintos hashcodes.
>Pero debemos saber cuales funcionarn y
cuales no (es decir, cuales nos permitirn
encontrar un objeto en la coleccin)

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; }
}
}

Implementando hashCode()
>La variable transient volver (luego de
serializar el objeto) con un valor por defecto,
en vez del valor que tena la variable al
momento de guardarla.
>En conclusin: las variables transient pueden
dar problemas en las implementaciones de
equals() y hashCode().

Contratos
>En Java, un contrato es un
conjunto de reglas que
deberan ser seguidas si
queremos que nuestras
implementaciones
funcionen de la forma
esperada.
>En otras palabras, si no seguimos los contratos,
nuestro cdigo posiblemente compile y corra,
pero podra fallar inesperadamente en su
ejecucin.

El contrato de equals
>Es reflexivo. Para cualquier referencia por
ejemplo x, x.equals(x) debera devolver true.
>Es simtrico. 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.

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 informacin 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 estn unidos por
un contrato conjunto que dice que si dos objetos son
equals, deben tener hashCodes idnticos.

El contrato de hashCode
>Siempre que es invocado con el mismo objeto
ms de una vez durante la ejecucin de una
aplicacin Java, el hashCode () debe devolver
constantemente el mismo nmero entero,
siempre y cuando la informacin utilizada
para las comparaciones equals() no
modifiquen el objeto. Este entero no es
necesario que mantenga la coherencia de la
ejecucin en una aplicacin a otra ejecucin
de la misma aplicacin.

El contrato de hashCode (II)


>Si dos objetos son iguales de acuerdo con el mtodo
equals(java.lang.Object), entonces se pide que el
mtodo hashCode() en cada uno de los dos objetos
debe devolver el mismo resultado entero.
>No es necesario que si dos objetos son desiguales en
funcin del mtodo 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 produccin de
distintos resultados enteros para los objetos puede
mejorar el rendimiento de tablas hash.

El contrato de hashCode (III)


>Debemos recordar lo siguiente:
Condicin
x.equals(y) == true

Requisito

Permitido (aunque no
requerido)

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

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.
}

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 mtodos
26. }

Collections
>El API comienza con la definicin de varias
interfaces, de las cuales debemos conocer las
siguientes para el examen:
>Collection
>List
>Queue
>Set
>Map
>SortedSet
>SortedMap

Collections (II)
>Hay un gran nmero de clases concretas,
para el examen alcanzar con conocer las
siguientes 13:
Maps

Sets

Lists

HashMap

HashSet

ArrayList

Hashtable

LinkedHashSet

Vector

TreeMap

TreeSet

LinkedSet

LinkedHashMap

Queues
PriorityQueue

Utilities
Collections
Arrays

La palabra collection
>Es fcil confundir Collection con
Collections, y viceversa.
>Collections es una clase, con mtodos
utilitarios.
>Mientras que Collection es una interfaz con
declaraciones de mtodos comunes a la
mayora de las colecciones, incluyendo add(),
remove(), contains(), size() e iterator().

La palabra collection (II)


>collection (c minscula), representa una de las
estructuras de datos en las cuales se almacenan los
objetos para luego iterar sobre ellos.
>Collection (C mayscula), es la interfaz
java.util.Collection, la cual extienden Set, List y
Queue (no existen implementaciones directas de
Collection).
>Collections (C mayscula, termina en s), es la
clase java.util.Collections, que contiene gran
cantidad de mtodos estticos para utilizar en
colecciones.

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
sern procesadas.

Comparacin entre List, Set y Map

Ordenada
>Cuando una coleccin 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 mtodo sort en
una coleccin no ordenada.

Sorted
>Significa que el orden de una coleccin esta
establecido por una regla.
>Una regla para ordenar un conjunto de palabras
podra ser colocarlas en orden alfabtico.
>Para nmeros enteros, podramos 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.

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 mtodos relacionados con el
ndice (por ej.: get(int index), indexOf(Object
o), add(int index, Object obj))
>Las tres implementaciones de List estn
ordenadas por el valor del ndice.

ArrayList
>La forma de ver esta implementacin es que
es un array que puede crecer.
>Esta ordenada, pero no es sorted (slo est
ordenada por el ndice).
>Se utiliza cuando necesitamos iterar
rpidamente, pero no necesitamos agregar o
borrar elementos.

Vector
>Un vector es bsicamente lo mismo que un
ArrayList, pero sus mtodos estn
sincronizados.
>En general, es preferible utilizar ArrayList en
vez de Vector, dado que los mtodos
sincronizados reducen la performance de
nuestro programa.
>Vector y ArrayList son las nicas clase que
implementan RandomAccess.

LinkedList
>Est ordenada por el ndice, pero a diferencia
de ArrayList, los elementos estn doblemente
vinculados.
>LinkedList itera ms lento que un ArrayList,
pero las inserciones y los borrados son ms
rpidos.
>Soporta los mtodos peek(), poll() y offer() (a
partir de Java 5, porque implementa Queue).

Interfaz Set
>Un Set no permite
duplicados.
>Se utiliza equals()
para determinar si
dos objetos son
identicos.

HashSet
>No esta orden, ni utiliza una regla de
ordenamiento.
>Utiliza el hashcode del elemento para
localizarlo. Cuanto mejor la implementacin,
mejor performance en el acceso.
>Se utiliza cuando el nico requisito es no
tener duplicados y no importa el orden al
iterarlo.

LinkedHashSet
>Es una versin ordenada de HashSet.
>Mantiene una lista doblemente vinculada de
los elementos.
>El orden de iteracin se corresponde con el de
insercin de los elementos.

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.

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.

HashMap
>HashMap es una coleccin 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 mltiples nulls
entre los valores de la coleccin.

Hashtable
>Es la versin sincronizada de HashMap.
>Al igual que el Vector, conviene utilizarlo solo
cuando es necesario que los mtodos sean
sincronizados, de otra forma, estaremos
reduciendo la performance de nuestro
programa en forma innecesaria.
>Un Hashtable no acepta ningn null.

LinkedHashMap
>Mantiene el orden de insercin.
>Esto hace que sea algo ms lento que
HashMap para agregar y remover elementos.
>Sin embargo, la iteracin a travs de los
elementos es ms rpida.

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

Interfaz Queue
>Un Queue est diseado 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 mtodos estndar de las
colecciones y aaden mtodos para agregar y
quitar elementos y evaluar los elementos del
queue.

PriorityQueue
>Incluida en Java
5.
>Su propsito es
crear una cola
ordenada por
prioridad en vez
de utilizar el
enfoque FIFO.
>Sus elementos se ordenan con una regla de
ordenamiento.

Resumen

ArrayList
>Crece dinmicamente.
>Provee mejores mecanismos de insercin y
bsquedas que los arrays.
List myList = new ArrayList();

>A partir de Java 5, podemos utilizar genricos:


List<String> myList = new
ArrayList<String>();

ArrayList (II)
>ArrayList<String> es similar en muchas formas
a String[].
>Sin embargo, ArrayList<String> es ms
verstil.
>Por ejemplo:
List<String> list = new
ArrayList<String>();
String[] list = new String[xxx];
//xxx debe ser un valor especfico

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 conversin
automticamente.
myInts.add(42); // Java 5.0

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);

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, slo funcionar cuando los
elementos de la lista implementen
Comparable.

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 mtodo compareTo.

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

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.

Ordenando con Comparator


>A diferencia de Comparable, un Comparator
no fuerza la modificacin 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());
}
}

Comparable Vs. Comparator


java.lang.Comparable

java.util.Comparator

intobjOne.compareTo(objTwo)

intcompare(objOne,objTwo)

Retorna
NegaGvosiobjOne<objTwo
CerosiobjOne==objTwo
PosiGvosiobjOne>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

Usando Listas
>hasNext() retorna true si hay al menos un
elemento mas en la coleccin que estamos
recorriendo.
>Invocar hasNext no nos posiciona en el elemento
siguiente.

>next() retorna el siguiente elemento en la


coleccin.
>Invocar next nos posiciona el elemento que se
encuentra a continuacin del que acabamos de
retornar.

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();

Usando Sets
>Recuerden que los Sets son sin duplicados.
boolean[] ba = new boolean[5]
//definicin 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());

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

Usando Sets (III)


>El orden de los objetos impresos no es
predecible. HashSet y LinkedHashSet no
garantizan ningn orden.
>La cuarta invocacin falla, puesto que
intentamos agregar un elemento que ya era
parte del conjunto.
>Por qu aparece la excepcin?

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");

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 mtodos que no se
encuentran en otras subinterfaces de
Collection: peek, poll y offer.

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 coleccin.
>poll() retorna el elemento de mayor prioridad en la
coleccin, y lo remueve de la misma.

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() + " ");

>Cul es el resultado?

Preguntas

Potrebbero piacerti anche