Resumen OCP(SCJP): Capítulo 7. Genéricos y Colecciones

por | Julio 8, 2013

SOBRESCRIBIENDO HASHCODE() Y EQUALS() (OBJETIVO 6.2)

  • Si no se sobrescribe el método equals(), objetos diferentes no pueden ser considerados iguales.

Los características más importantes del método equals() son:

  • Es reflexivo: x.equals(x) es true.
  • Es simétrico: Si x.equals(y) es true, entonces y.equals(x) debe ser true.
  • Es transitivo: Si x.equals(y) es true, y y.equals(z) es true, entonces z.equals(x) es true.
  • Es consistente: Múltiples llamadas a x.equals(y) deben retornar el mismo resultado.
  • Null: Si x no es null, entonces x.equals(null) es false.

Condición Requerido No Requerido(Pero Permitido)
x.equals(y) == true x.hashCode() == y.hashCode()
x.hashCode() == y.hashCode() x.equals(y) == true
x.equals(y) == false No hashCode()requirements
x.hashCode() != y.hashCode() x.equals(y) == false

COLLECTIONS (OBJECTIVO 6.1)

  • HashMap, Hashtable, LinkedHashMap, HashSet y LinkedHashSet utilizan el código de hash.
  • Es legal que el método hashCode() devuelva el mismo valor para todas las instancias de una clase. Salvo que en la práctica esto no es eficiente.

Los características más importantes del método hashCode() son:

  • Es consistente: Múltiples llamados a x.hashCode() devuelven el mismo valor entero.
  • Si x.equals(y) es true, x.hashCode() == y.hashCode() es true.
  • Si x.equals(y) es false, entonces x.hashCode() == y.hashCode() puede ser tanto true como false, pero si es false la implementación tiende a tener mayor eficiencia.
Maps Sets Lists Queues Utilities
HashMap HashSet ArrayList PriorityQueue Collections
Hashtable LinkedHashSet Vector Arrays
TreeMap TreeSet LinkedList
LinkedHashMap
Class Map Set List Ordered(Ordenado) Sorted(Clasificado)
HashMap x No No
Hashtable x No No
TreeMap x Sorted By natural order or
custom comparison rules
LinkedHashMap x By insertion order
or last access order
No
HashSet x No No
TreeSet x Sorted By natural order or
custom comparison rules
LinkedHashSet x By insertion order No
ArrayList x By index No
Vector x By index No
LinkedList x By index No
PriorityQueue Sorted By to-do order

Ordenamiento

Comparable

public class Persona implements Comparable<Persona> {
    private Integer id;
    private String name;
    private Float height;
    private Long salary;
    private String emailId;
    private Date dob;    

    @Override
    public int compareTo(Persona persona) {
        return name.compareTo(persona.getName());
    }
}
Collections.sort(personas);

Comparator

public class Persona {
    private Integer id;
    private String name;
    private Float height;
    private Long salary;
    private String emailId;
    private Date dob;
}
public class PersonaComparator implements Comparator<Persona> {

    @Override
    public int compare(Persona o1, Persona o2) {
        return o1.getName().compareTo(o2.getName());
    }
}
Collections.sort(personas, new PersonaComparator());

ATRIBUTOS CLAVE DE LAS CLASES DE COLECCIÓN (OBJETIVO 6.1)

List: basadas en los índices de los elementos en la colección.
Set: Es un conjunto de elementos únicos. Es decir, no se permiten objetos duplicados. HashSet permite contener elementos de diferentes tipos. Pero una colección TreeSet no permite contener objetos que no sean comparables entre sí.
Map: Son colecciones con elementos compuestos de parejas clave/valor. Las claves de los elementos son únicas.

ArrayList: Rápida iteración y rápido acceso aleatorio.
Vector: Es como un ArrayList más lento, pero tiene sus métodos sincronizados.
LinkedList: Es bueno para agregar elementos al final, por ejemplo pilas y colas.
HashSet: Rápido acceso, asegura la no duplicación, no provee un orden.
LinkedHashSet: No posee elementos duplicados, itera por orden de inserción.
TreeSet: No posee elementos duplicados, itera en orden.
HashMap: Rápidas actualizaciones (clave/valor), permite una clave null y muchos valores null.
Hashtable: Es como un HashMap más lento, pero tiene sus métodos sincronizados. No permite valores null tanto en las claves como en los valores.
LinkedHashMap: Rápidas iteraciones, itera en orden de inserción o ultimo acceso. También permite valores null y una clave null.
TreeMap: Un mapa ordenado.
PriorityQueue: Una cola ordenada con las prioridades de sus elementos.

Ejemplos Colecciones Java 5

public static void main(String[] args) {

    Object obj = new Object();        
    Set tree = new TreeSet();//<-
    Set hash = new HashSet();

    tree.add("o");
    /*java.lang.Object cannot be
      cast to java.lang.Comparable*/
    tree.add(obj);//RunTimeException
        
    hash.add("o");
    hash.add(obj);
    hash.add(4);
        
    out.println("tree.size: " +tree.size());
    out.println("hash.size: "+hash.size());//3

    List lista = new ArrayList();
    lista.add("2");
    lista.add(34);
        
    out.println("lista.size: "+lista.size());

}

UTILIZANDO LAS CLASES DE COLECCIÓN (OBJETIVO 6.3)

  • A partir de Java 6 las clases TreeSet y TreeMap tienen nuevos métodos de navegación como floor() y higher().
  • Se pueden crear/extender sub-copias “respaldadas” de TreeSets y TreeMaps.

NavigableSet

Esta interface (implementada únicamente por TreeSet) posee diversos métodos de utilidad:

lower(): Devuelve el elemento menor al elemento pasado como parámetro.
floor(): Devuelve el elemento menor o igual al elemento pasado como parámetro.
higher(): Devuelve el elemento mayor al elemento pasado como parámetro.
ceiling(): Devuelve el elemento mayor o igual al elemento pasado como parámetro.
pollFirst(): Devuelve el primer elemento y lo elimina de la colección.
pollLast(): Devuelve el último elemento y lo elimina de la colección.
descendingSet(): Devuelve una copia de la colección en orden inverso.
headSet(e): Devuelve un subconjunto que termina en el elemento (excluido) e.
tailSet(e): Devuelve un subconjunto que comienza en el elemento (incluido) e.
subSet(s, e): Devuelve un subconjunto que comienza en el elemento (incluido) s y finaliza en el elemento (excluido) e

NavigableMap

Esta interface (implementada únicamente por TreeMap) posee diversos métodos de utilidad:

lowerKey(): Devuelve la clave menor a la clave pasada como parámetro.
floorKey(): Devuelve la clave menor o igual a la clave pasada como parámetro.
higherKey(): Devuelve la clave mayor a la clave pasada como parámetro.
ceilingKey(): Devuelve la clave mayor o igual a la clave pasada como parámetro.
pollFirstEntry(): Devuelve la primer pareja clave/valor y la elimina de la colección.
pollLastEntry(): Devuelve la ultima pareja clave/valor y la elimina de la colección.
descendigMap(): Devuelve una copia de la colección en orden inverso.
headMap(k): Devuelve un subconjunto que termina en la clave (excluida) k.
tailMap(k): Devuelve un subconjunto que comienza en la clave (incluida) k.
subMap(s, e): Devuelve un subconjunto que comienza en la clave (incluida) s y finaliza en la clave (excluida) e.

TreeMap<String, String> mymap= new TreeMap<String, String>();
mymap.put("a", "apple");
mymap.put("d", "date");
mymap.put("f", "fine");
mymap.put("p", "pear");

System.out.println(mymap.lowerKey("d")); //<
System.out.println(mymap.floorKey("d")); //<=
System.out.println(mymap.ceilingKey("f")); //>=
System.out.println(mymap.higherKey("f")); //>

SortedMap<String, String> subTail = new TreeMap<String, String>();
subTail = mymap.tailMap("d"); //comienza en la clave (incluida)
System.out.println(subTail); //	{d=date, f=fine, p=pear}

SortedMap<String, String> subHead = new TreeMap<String, String>();
subHead = mymap.headMap("f"); //termina en la clave (excluida)
System.out.println(subHead); //	{a=apple, d=date}

Queue

La colección PriorityQueue ordena sus elementos utilizando una prioridad definida por el usuario. La prioridad puede ser el orden natural, pero también se puede ordenar utilizando un objeto Comparator. La interface Queue posee métodos que no se encuentran en ninguna otra colección:

peek(): Devuelve el primer elemento de la cola (o el que tenga mayor prioridad).
poll(): Devuelve el primer elemento de la cola (o el que tenga mayor prioridad), y luego lo elimina de la cola.
offer(T o): Agrega un elemento al final de la cola (o en el lugar donde indique su prioridad).

GENÉRICOS (OBJETIVO 6.4)

  • Cuando se utiliza un comodín <? extends Dog>, la colección puede ser accedida pero no modificada.
  • List<?> es igual a List<? extends Object>.

Las asignaciones polimórficas aplican solo al tipo base, no al parámetro de tipo genérico:

List<Animal> l = new ArrayList<Animal>(); // válido
List<Animal> l = new ArrayList<Dog>(); // inválido

La regla de asignación polimórfica aplica en cualquier lugar en donde se pueda realizar una asignación:

void foo(List<Animal> l) { } // no puede tomar un argumento List<Dog>
List<Animal> bar() { } // no puede devolver un List<Dog>

EOF