Colecciones en Java



Descargar 21,6 Kb.
Fecha de conversión05.08.2017
Tamaño21,6 Kb.
  • vi. Colecciones
  • - interfaz Collection
  • - clases ArrayList, LinkedList, HashSet, TreeSet
  • - interfaz Map
  • - clases TreeMap, HashMap
  • - Iteratores: interfaz Iterator
  • vii. Clases anidadas e internas

Colecciones en Java

  • Permite almacenar y organizar objetos de manera útil para un acceso eficiente.
  • Se encuentran en el paquete java.util
  • Núcleo de abstracciones de colecciones de utilidad (interfaces) e implementaciones ampliamente útiles.
  • Las interfaces proporcionan métodos para todas las operaciones comunes y las implementaciones concretas especifican la decisión de las operaciones no permitidas.
  • (java.lang.UnsupportedOperationException)
  • Sobre los elementos se puede iterar (Iterator)

Jerarquía de colecciones

  • Collection
  • ListIterator
  • Iterator
  • Map
  • AbstractMap
  • SortedMap
  • AbstractSequentialList
  • TreeMap
  • HashMap
  • SortedSet
  • AbstractSet
  • AbstractList
  • AbstractCollection
  • Set
  • List
  • HashSet
  • TreeSet
  • ArrayList
  • LinkedList
  • extends
  • implements
  • class
  • interface
  • devuelve
  • devuelve
  • devuelve

Interfaz Collection (1/2)

  • Collection
        • int size()
        • boolean empty()
        • boolean contains(Object elem)
        • Iterator iterator()
        • Object[] toArray(), Object[] toArray(Object dest[])
        • boolean add(Object elem),
        • boolean remove(Object elem)
        • void clear()
  • List – Una colección cuyos elementos permanecen en un orden particular a menos que se modifique la lista (no significa lista enlazada aunque es una posible implementación).
        • void add(int index, Object element)
        • Object remove(int index)
        • Object get(int index)
        • Object set(int index, Object element)
        • int indexOf(Object o)
        • int lastIndexOf(Object o)
        • List subList(int min, int max)

Interfaz Collection (2/2)

  • Set – Una colección (conjunto) donde no puede haber elementos repetidos, y cuyos elementos no se almacenan necesariamente siguiendo un orden particular.
    • Mismos métodos que Collection con otro contrato.
  • SortedSet – Conjunto con elementos ordenados.
    • Object first()
    • Object last()
    • SortedSet subSet(Object fromElement, Object toElement)
    • SortedSet headSet(Object toElement)
    • SortedSet tailSet(Object fromElement)

Interfaz Map

  • Map
    • Un objeto que asocia claves con valores.
    • No puede tener claves duplicadas.
    • Object put(Object key, Object value);
    • Object remove(Object key); Object get(Object key);
    • containsKey, containsValue, isEmpty, size
    • Proporciona tres vistas de colección: colección de claves (keySet), colección de valores (values), colección de asociaciones clave-valor (entrySet).
  • SortedMap: Un mapa cuyas claves están ordenadas.
    • Object firstKey(), Object lastKey(), SortedMap subMap(Object minKey, Object maxKey), SortedMap headMap(Object maxKey), SortedMap tailMap(Object minKey)

Iteración

  • Collection >> Iterator iterator();
  • interface Iterator{
  • boolean hasNext();
  • /* Devuelve true si la iteración tiene mas elementos */
  • Object next();
  • /* Devuelve el siguiente elemento de la iteración
  • Lanza excepción NoSuchElementException */
  • void remove();
  • /* Elimina el último elemento devuelto por la iteración
  • Está capacitado para decir que no lo implementa
  • UnsupportedOperationException */
  • }
  • La interfaz ListIterator extiende a Iterator y maneja un objeto List ordenado. Permite iterar hacia delante y hacia atrás.

Ejemplo de uso de Iteradores

  • Cálculo del gasto total de un departamento
  • public double gastoDpto(){
  • double gasto=0;
  • Iterator it=plantilla.iterator();
  • while (it.hasNext()){
  • gasto+=((Empleado)it.next()).getSueldo();
  • }
  • return gasto;
  • }
  • Siendo plantilla una colección que implemente la interfaz Collection

Implementaciones de Collection

  • LinkedList – Una implementación de una lista doblemente enlazada. La modificación es poco costosa para cualquier tamaño, pero el acceso aleatorio es lento. Útil para implementar colas y pilas.
    • getFirst, getLast, removeFirst, removeLast, addFirst, addLast
  • ArrayList – Una lista implementada utilizando un array de dimensión modificable. Es costoso añadir o borrar un elemento cerca del principio de la lista si ésta es grande, pero es relativamente poco costoso de crear y rápido para acceso aleatorio.
  • HashSet – Un Set implementado mediante una tabla hash. Es una buena implementación de propósito general por lo que la búsqueda, la adición y eliminación son insensibles al tamaño de los contenidos.
  • TreeSet – Un SortedSet implementado utilizando un árbol binario equilibrado. Es más lento para buscar o modificar que un HashSet, pero mantiene los elementos ordenados. Asume que los elementos son comparables si no se le ha pasado un comparator en el constructor.
  • Todas son Cloneable y Serializable

Convenciones sobre excepciones

  • UnsupportedOperationException
    • Métodos opcionales en la implementación de una interfaz
  • ClassCastException
    • El tipo del elemento que se desea insertar no es del tipo apropiado
  • IllegalArgumentException
    • El valor del elemento no es apropiado para la colección
  • NoSuchElementException
    • La colección de la que se quiere devolver un elemento está vacía
  • NullPointerException
    • Se pasa como argumento una referencia con valor null cuando la colección no admite este valor.

Declaración de colecciones

  • import java.util.*;
  • public class ColeccionSimple {
  • public static void main( String args[] ) {
  • List c = new ArrayList();
  • for( int i=0; i < 10; i++ )
  • c.add(new Integer(i));
  • Iterator it = c.iterator();
  • while( it.hasNext() )
  • System.out.println(it.next());
  • }
  • }
  • interfaz
  • Clase concreta

Implementaciones de Map

  • HashMap
    • Una implementación de Map con una tabla hash.
    • El método hashCode de cada clave se utiliza para seleccionar un lugar en la tabla
    • Una colección de utilidad muy general con tiempos relativamente cortos de búsqueda e inserción.
  • TreeMap
    • Una implementación de SortedMap utilizando un árbol binario equilibrado que mantiene sus elementos ordenados por clave.
    • Útil para conjuntos de datos ordenados que requieren una búsqueda por clave moderadamente rápida.
    • Asume que los elementos son comparables si no se le ha pasado un comparator en el constructor.

Ejemplo 1/2

  • Generar números al azar (Math.random) y contar cuantas veces sale cada uno.
  • HashMap = Colección de pares (clave-valor)
    • Clave = número aleatorio generado
    • Valor = contador que acumula las veces que ha aparecido
    • class Contador {
    • private int i;
    • public Contador(){ i=1;}
    • public void incrementar(){++i;}
    • public String toString() {
    • return Integer.toString(i);
    • }
    • }

Ejemplo 2/2

  • class Estadistico {
  • public static void main( String args[] ) {
  • HashMap tabla = new HashMap();
  • for(int i=0; i < 10000; i++) {
  • // Generar un número entre 0 y 20
  • Integer num = new Integer((int)(Math.random()*20));
  • if(tabla.containsKey(num))
  • //Incrementamos el contador asociado al número
  • ((Contador)tabla.get(num)).incrementar();
  • else
  • //Añadimos nuevo par: numero-contador
  • tabla.put(num, new Contador());
  • }
  • System.out.println(tabla);
  • }
  • }

Las utilidades de Collections

  • public static Object min(Collection col)
  • public static Object max(Collection col)
  • public static Object min(Collection col, Comparator comp)
  • public static Object max(Collection col, Comparator comp)
  • public static void reverse(List lista)
  • public static void copy(List dst, List fnt)
  • public static void sort(List lista)
  • public static void sort(List lista, Comparator comp)
  • public static int binarySearch(List lista, Object clave)
  • public static int binarySearch(List lista, Object clave, Comparator comp)

Conclusiones

  • Si un método tiene que devolver (pasar como parámetro) una colección de objetos, el tipo será Iterator o cualquiera de las interfaces de colección.
  • El tipo de la declaración de los atributos y variables locales será cualquiera de las interfaces de colección.
    • List lista = new ArrayList();
    • Excepción: LinkedList si la utilizamos como pila o cola.
  • Utilizar SIEMPRE Iterator para el recorrido de cualquier colección.

Clases anidadas e internas

  • Un clase o interfaz se puede declarar dentro de otras clases o interfaces.
  • Un tipo anidado se considera parte del tipo que lo contiene.
  • Cada uno puede acceder a los miembros del otro (incluso los privados).
  • Los tipos anidados pueden declararse:
    • static (clases anidadas): permite una estructuración simple de tipos
    • No estático (clases internas): define una relación especial entre el objeto anidado y el objeto de la clase que lo contiene
  • Se recomienda un único nivel de anidamiento
  • Toda clase interna produce un archivo .class
  • ClaseExterna.class
  • ClaseExterna$ClaseInterna.class

Clases anidadas estáticas

  • El modificador static precede al nombre de la clase.
  • Igual que los miembros estáticos son independientes de los objetos que se creen de la clase externa (no se puede acceder a los campos no estáticos).
  • Sirve como mecanismo para definir tipos lógicamente relacionados.
  • La clases anidada se comporta como cualquier otra clase:
    • Se pueden definir subclases. La clase que extienda a la clase anidada no hereda su privilegio de acceso a la clase que la contiene
    • Implementar un interfaz
    • Declararse como abstract o final
  • Declaración de una variable:
  • ClaseExterna.ClaseAnidada var;

Ejemplo: Definir estructura de datos asociadas

  • class Pila { private Nodo cabeza;
  • private static class Nodo {     Object valor;
  • Nodo siguiente;
  • Nodo(Object v, Nodo s){
  • valor = v;
  • siguiente = s;
  • }
  • }
  • public void push (Object obj){
  • cabeza = new Nodo (obj,cabeza);
  • }
  • public Object pop (){
  • Object primero = cabeza.valor;
  • cabeza = cabeza.siguiente;
  • return primero;
  • }
  • }

Clases internas

  • Clases anidadas no estáticas.
  • Un objeto de la clase interna se asocia siempre con un objeto de la clase que la incluye, de manera que ve los atributos y métodos de la clase externa como propios.
  • Los objetos de la clase interna se crean dentro de los métodos de instancia de la clase que las incluye.
  • El objeto receptor del método de instancia se asocia por defecto con el objeto interno.
  • La declaración es igual a la de cualquier otra clase con la restricción de que no pueden tener miembros estáticos (excepto si son finales).
  • Puede ocultar atributos y métodos de la clase envolvente.

Ejemplo: Creación del objeto de la clase interna dentro de un método de instancia de la clase envolvente

  • class CuentaBancaria{
  • private long numero;
  • private long saldo;
  • private Operacion ultimaOp;
  • private class Operacion{
  • String descripcion;
  • long cantidad;
  • ...
  • public String toString(){
  • return numero + “: ”+ descripcion+” “+cantidad;
  • }
  • }
  • ...
  • public void reintegro(long cantidad){
  • saldo -=cantidad;
  • ultimaOp= new Operacion(“reintegro”, cantidad);
  • }
  • }

Ejemplo: acceso a métodos ocultos

  • class Externa{
  • void imprimir(){}
  • class Interna{
  • void imprimir(){} //oculta los métodos del mismo
  • //nombre en la clase externa
  • void mostrar(){
  • imprimir();
  • Externa.this.imprimir();
  • //OK.Invocación explícita al método de la clase Externa

Ejemplo:Acceso a todos lo miembros de quien lo contiene

  • interface Iterator{
  • boolean hasNext();
  • Object next();
  • void remove();
  • }
  • public class Secuencia{
  • private Objects[] contenido;
  • private int siguiente = 0;
  • public Secuencia(int tamaño){
  • contenido = new Object[tamaño];
  • }
  • public void añadir(Object obj){
  • if (siguiente
  • contenido[siguiente]=obj;
  • siguiente++;
  • }
  • }

Ejemplo (continuación)

  • //Clase interna accede al atributo contenido de la clase Secuencia
  • private class CIterator implements Iterator{
  • private int pos=0;
  • public boolean hasNext(){
  • return (pos < contenido.length);
  • }
  • public Object next(){
  • if (pos >= contenido.length)
  • throw new NoSuchElementException();
  • return contenido[pos++];
  • }
  • public void remove(){
  • throw new UnsupportedOperationException();
  • }
  • }//Fin de la clase Interna
  • public Iterador iterador(){
  • return new CIterador();
  • }
  • } //Fin de la clase Secuencia

Uso del iterador de la clase Secuencia

  • Secuencia s = new Secuencia(10);
  • ...
  • Iterator iter = s.iterator();
  • while (iter.hasNext()){
  • System.out.println(iter.next());
  • }

Clases internas locales

  • Pueden definirse en cualquier punto del código (ej. dentro de un método).
  • Inaccesibles desde el exterior del bloque de código donde se definen.
  • Pueden acceder a todas las variables que estén dentro del alcance de donde se define (ej. variables y/o parámetros de un método) si se declaran como final.

Ejemplo: Iterador creado dentro de un método

  • public Iterator iterator(){
  • class CIterador implements Iterator{
  • private int pos=0;
  • public boolean hasNext(){
  • return (pos < contenido.length);
  • }
  • public Object next(){
  • if (pos>= contenido.length)
  • throw new NoSuchElementException();
  • return contenido[pos++];
  • }
  • public void remove(){
  • throw new UnsupportedOperationException();
  • }
  • }
  • return new CIterador();
  • }

Clases internas anónimas

  • Se definen en el mismo momento en el que se instancian con new.
  • No puede tener una cláusula explícita extends o implements.
  • No puede tener constructores explícitos declarados.
  • Permanece la necesidad de invocar a un constructor de la superclase.
  • Ejemplo: subclase anónima que invoca al constructor y redefine un método
  • SuperClase var = new SuperClase (valor){
  • public void met(Object obj){
  • //redefinicion de met
  • }
  • };

Ejemplo: Iterador anónimo

  • public Iterator iterator(){
  • return new Iterator(){
  • private int pos=0;
  • public boolean hasNext(){
  • return (pos < contenido.length);
  • }
  • public Object next(){
  • if (pos>= contenido.length)
  • throw new NoSuchElementException();
  • return contenido[pos++];
  • }
  • public void remove(){
  • throw new UnsupportedOperationException();
  • }
  • };
  • }

Ventajas de la clases anidadas e internas

  • Reduce los conflictos de nombres. Proporciona una organización estructural adicional a los paquetes y clases.
    • Ejemplo: Lista.Nodo, Arbol.Nodo
  • Implementar una clase (la clase interna) que necesite acceder a la estructura interna de otra porque necesite devolver objetos con privilegios.
    • Ejemplo: iterador sobre un escenario
  • Callbacks-Simplifica la gestión de eventos (GUI).


La base de datos está protegida por derechos de autor ©absta.info 2016
enviar mensaje

    Página principal