Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tema 1 Introduccion Al Java Collections Framework PDF
Tema 1 Introduccion Al Java Collections Framework PDF
CONTENIDO
1 INTRODUCCIÓN.............................................................................................................................................................2
1.1. ELEMENTOS DEL JCF..................................................................................................................................................2
2 INTERFAZ COLLECTION............................................................................................................................................3
3 ITERADORES...................................................................................................................................................................7
3.1. INTERFAZ ITERATOR...................................................................................................................................................7
3.2. INTERFAZ LISTITERATOR..........................................................................................................................................10
4 INTERFACES COMPARABLE Y COMPARATOR.................................................................................................16
4.1. INTERFAZ COMPARABLE...........................................................................................................................................16
4.2. INTERFAZ COMPARATOR..........................................................................................................................................19
4.3. ¿CUÁNDO USAR COMPARABLE Y COMPARATOR?....................................................................................................23
5 UTILIDADES PARA OBJETOS CONTENEDORES: CLASE JAVA.UTIL.COLLECTIONS...........................23
5.1. ORDENACIÓN............................................................................................................................................................24
5.2. INVERSIÓN DEL ORDEN.............................................................................................................................................25
5.3. BÚSQUEDA................................................................................................................................................................25
5.4. COPIAR LISTA...........................................................................................................................................................25
5.5. RELLENAR UNA LISTA..............................................................................................................................................26
5.6. MÁXIMOS Y MÍNIMOS...............................................................................................................................................27
5.7. CONSTANTES.............................................................................................................................................................27
6 CLASE ARRAYS (AMPLIACIÓN)..............................................................................................................................28
6.1. TRATAR MATRIZ COMO LISTA..................................................................................................................................28
6.2. MÉTODOS SIMILARES A LOS DE COLLECTIONS.........................................................................................................28
7 CLASE JAVA.LANG.MATH........................................................................................................................................28
8 BIBLIOGRAFÍA.............................................................................................................................................................30
1 Introducción
En la versión 1.2 del JDK se introdujo el Java Collections Framework o “estructura de colecciones
de Java” (en adelante JCF). Se trata de un conjunto de clases e interfaces que mejoran
notablemente las capacidades del lenguaje respecto a estructuras de datos. Además,
constituyen un excelente ejemplo de aplicación de los conceptos propios de la programación
orientada a objetos.
Interfaces de soporte:
Iterator: sustituye a la interfaz Enumeration. Dispone de métodos para recorrer una
colección y para borrar elementos.
ListIterator: deriva de Iterator y permite recorrer lists en ambos sentidos.
Comparable: declara el método compareTo() que permite ordenar las distintas
colecciones según un orden natural (String, Date, Integer, Double, …).
Comparator: declara el método compare() y se utiliza en lugar de Comparable
cuando se desea ordenar objetos no estándar o sustituir a dicha interfaz.
Clases históricas: Son las clases Vector y Hashtable presentes desde las primeras versiones
de Java. En las versiones actuales, implementan respectivamente las interfaces List y Map,
aunque conservan también los métodos anteriores.
Clase Arrays: Es una clase de utilidad introducida en el JDK 1.2 que contiene métodos static
para ordenar, llenar, realizar búsquedas y comparar los arrays clásicos del lenguaje. Permite
también ver los arrays como lists.
2 Interfaz Collection
La interfaz Collection es implementada por los conjuntos (sets) y las listas (lists). Esta
interfaz, declarada en el paquete java.util, declara una serie de métodos generales utilizables
con Set y List.
Los métodos indicados como “// opcional” pueden no estar disponibles en algunas
implementaciones, como por ejemplo en las clases que no permiten modificar sus objetos. Por
supuesto dichos métodos deben ser definidos, pero lo que hacen al ser llamados es lanzar una
UnsupportedOperationException.
Otros Métodos
boolean equals(Object). Implementa la igualdad o equivalencia. Retorna true si el objeto
que llama al método es equivalente al que se pasa como parámetro. Devuelve false si el
argumento es nulo.
int hashCode(). A la hora de acceder, añadir, o eliminar un objeto contenido en un
hashtable, la implementación de dicha estructura invocará este método sobre el objeto
para obtener un int que pueda ser utilizado en la elaboración del índice en el hashtable.
Durante la ejecución de un programa este método ha de retornar el mismo int siempre
que sea invocado sobre el mismo objeto. Siempre y cuando sea factible ha de ser único
para cada objeto. Por ello, aunque esta implementación no es requerida, el método
devuelve la dirección física del objeto en memoria.
Object[] toArray(). Permiten convertir una colección en un array.
Un aspecto importante es que las colecciones sólo pueden contener objetos. Por ello, en
versiones anteriores, Java no permitía que a una colección se pudieran añadir elementos que no
fueran objetos, es decir, de tipos básicos o primitivos, es decir, que una instrucción como
c.add(20) era incorrecta, y se tenía que sustituir por c.add(new Integer(20)), en la que se usa la
envoltura Integer. A partir de la versión Java 5 fueron integrados los mecanismos de auto-
boxing y auto-unboxing para permitir la conversión de valores primitivos hacia sus
respectivos objetos (envolturas) de manera directa y sin mayores complicaciones. Es decir, que
ya sí se permiten instrucciones del tipo c.add(20).
Ejemplo:
// Colección c1
c1.add(40);
c1.add(50);
c1.add(60);
c2.remove(new Integer(20));
// Comparación de colecciones
if (c1.equals(c2))
System.out.println("Son iguales");
else
System.out.println("Son distintas");
if (c1.containsAll(c2))
System.out.println("c2 contenida en c1");
else
System.out.println("c2 no contenida en c1");
}
}
NOTA: Aunque la interfaz Collection se puede usar para instanciar objetos, su principal
cometido es definir los métodos comunes a todas las colecciones. Por ello, lo normal es usar
algunas de sus interfaces hijas (List, Set o SortedSet). Así pues, a partir de ahora usaremos el
interfaz List como ejemplo de colección, ya que es más apropiado.
3 Iteradores
Los objetos de tipo iterador permiten recorrer colecciones. Disponen de un conjunto de métodos
que permiten avanzar sobre la colección y obtener los objetos de ésta durante un recorrido para
su tratamiento. Existen dos interfaces declarados en el JCF: java.util.Iterator, que dispone de
métodos para recorrer una colección y para borrar elementos; y java.util.ListIterator, que
permite recorrer una lista en ambos sentidos, siendo éste segundo descendiente del primero.
remove(): Elimina de la colección el último elemento retornado por next. Solo puede ser
llamado una vez por cada llamada a next, y siempre después de éste. Es la única forma
segura de eliminar un elemento mientras se está recorriendo una colección. Eleva
IllegalEstateException si no se cumplen las condiciones expuestas para la llamada; y
UnsupportedOperationException si la implementación de este interfaz no incluyó este
método (ya que es opcional).
Iterator it = colección.iterator();
while (it.hasNext())
{
Tipo obj = (<Casting>)it.next();
TRATAR obj
}
Para los siguientes ejemplos, usaremos la clase Persona y la interfaz Empleado, definidos de la
siguiente forma:
// Inicializa la lista c
Ejemplo: Eliminar elementos de una colección de Empleados. Este ejemplo es realizado usando
la interfaz Empleado en vez de la clase Persona para rellenar la colección. En este caso,
pretendemos borrar todos los empleados de la colección cuya edad sea superior a 24 años.
// Inicializa la lista c
Empleado e1 = new Persona("Pepe", "Lopez Perez", 25);
Empleado e2 = new Persona("Lola", "Lopez Aguilar", 23);
Empleado e3 = new Persona("Pepe", "Lopez Perez", 21);
Empleado e4 = new Persona("Antonio", "lopez Perez", 25);
Empleado e5 = new Persona("Alicia", "Sanchez Olmo", 21);
c.add(e1); c.add(e2); c.add(e3); c.add(e4); c.add(e5);
// Recorrido: Imprime la lista elemento a elemento
Iterator it = c.iterator();
while(it.hasNext())
System.out.println((Empleado)it.next());
}
}
Este tipo especial de iterador (deriva de la interfaz Iterator) sólo es válido para recorrer
listas (List), nunca Collection, Set o SortedSet. Añade métodos a Iterator para iterar hacia
atrás, para insertar o remplazar durante la iteración y para obtener la posición del puntero
interno.
Entre cada par de elementos, y también antes del primero y después del último existe una
posible posición del iterados. Los elementos se numeran desde 0 a n-1, pero los valores válidos
para el índice son de 0 a n. Puede suponerse que el índice i está en la frontera entre los
elementos i-1 e i. Por ejemplo:
El interfaz List incorpora dos métodos para asignar o inicializar un ListIterator, en concreto, el
método ListIterator() de una lista devuelve un ListIterator cuyo puntero es cero. El método
ListIterator(int) posiciona el puntero en el índice int.
next(): devuelve el elemento en cuyo índice se halla el puntero y avanza una posición el
valor del mismo. La primera vez que se invoca sobre el objeto retornado por el método
ListIterator() devuelve el primer elemento de la lista. Cuando se invoca sobre el objeto
retornado por ListIterator(int) devuelve el elemento de índice int. Si int fuera el tamaño
de la lista o si la iteración ha alcanzado el final de la lista, lanzaría la excepción
NoSuchElementException.
objeto devuelto por ListIterator(int) devuelve el objeto situado en el índice int-1. También
lanza NoSuchMethodException si la iteración ha alcanzado el principio de la lista.
nextIndex(): devuelve el índice del elemento que sería retornado por la próxima
llamada a next(), es decir la posición actual del puntero. Si el puntero se encuentra al
final de la colección devuelve su tamaño.
previousIndex(): devuelve el índice del elemento que sería retornado por la próxima
llamada a previous(), es decir la posición actual del puntero menos uno. Devuelve -1 si el
puntero se encuentra al comienzo de la lista.
remove(): elimina de la lista el último elemento retornado por next() o previous(). Sólo
puede ser llamado una vez por cada llamada a next() o previous(), y sólo si no se invocó
add() o remove() después. Los índices de los elementos posteriores son decrementados
en uno. Lanza UnsupportedOperationException si la implementación de este interfaz no
incorporó este método; e IllegalStateException si next o previous no fueron llamados, o
bien se invocó add o remove tras la última llamada a next o previous.
set(Object) remplaza el último elemento producido por next o previous por el objeto
especificado. Puede ser invocado varias veces sin necesidad de llamar nuevamente a
next o previous, siempre y cuando no aparezcan add o remove entre dichas llamadas.
Lanza las siguientes excepciones: UnsupportedOperationException, si la
implementación de este interfaz no incorporó este método; ClassCastException, si el
tipo de este objeto impidió su adición a una lista, IllegalStateException, si este objeto
infringe alguna restricción que impida su adicción a la lista, o bien, next o previous no
fueron llamados, o lo fueron pero después de la invocación a add o remove.
Ejemplo:
import java.util.*;
public class TestListIterator{
public static void main(String args[]){
Se dice que las clases que implementan esta interfaz cuentan con un “orden natural”. Este
orden es total, es decir, que siempre han de poder ordenarse dos objetos cualesquiera del la
clase que implementa este interfaz. La interfaz Comparable declara el método compareTo() de
la siguiente forma:
que compara su argumento implícito con el que se le pasa por ventana. Este método devuelve
un entero negativo, cero o positivo según el argumento implícito (this) sea anterior, igual o
posterior al objeto obj., respectivamente.
Si se redefine, el método compareTo() debe ser programado con cuidado: es muy conveniente
que sea coherente con el método equals() y que cumpla la propiedad transitiva.(Si X<Y y
Y<Z => X<Z)
Las listas y las tablas cuyos elementos implementan Comparable pueden ser ordenadas con los
métodos Collections.sort() y Arrays.sort(). Por ejemplo, si una clase implementa
Comparable, se puede utilizar en las siguientes acciones sin necesidad de un Comparator:
// Empleado.java
public interfaz Empleado{
public String getNombre();
public String getApellidos();
public int getEdad();
// No se añade compareTo, ya que está declarado en la interfaz Comparable
}
// Persona.java
public class Persona implements Comparable, Empleado{
private String nombre, apellidos;
private int edad;
//TestEmpleado.java
import java.util.*;
public class TestEmpleado{
public static void main(String args[]){
List c = new ArrayList();
}
}
Lopez Perez, Pepe (25) es mayor que Lopez Aguilar, Lola (23)
Lista Original:
[Lopez Perez, Pepe (25), Lopez Aguilar, Lola (23), Lopez Perez, Pepe (21), lopez Perez,
Antonio (25), Sanchez Olmo, Alicia (21)]
Ordenación:
[Lopez Aguilar, Lola (23), Lopez Perez, Pepe (21), Lopez Perez, Pepe (25), Sanchez Olmo,
Alicia (21), lopez Perez, Antonio (25)]
Nótese que tras la ordenación, la persona “lopez Perez, Antonio (25)” es la última al comenzar
su apellido por minúscula.
Si una clase ya tiene un criterio de ordenación natural (interfaz Comparable) y se desea tener
un criterio de ordenación diferente, por ejemplo descendente o dependiente de otros campos,
es necesario crear una clase que implemente dicho criterio. Esta clase, que se denomina
comparador, es independiente de la clase objeto de la ordenación y deberá implementar la
interfaz Comparator del paquete java.util. Un comparador es por tanto una clase que define
un criterio de ordenación de otras clases.
Así, la clase comparadora deberá implementar la interfaz Comparator, y por tanto el método
compare, de la siguiente forma:
El método compare() devuelve un entero negativo, cero o positivo según su primer argumento
sea anterior, igual o posterior al segundo (así asegura un orden ascendente). La
implementación debe asegurar que:
Es muy importante que compare() sea compatible con el método equals() de los objetos que
hay que mantener ordenados. Su implementación debe cumplir unas condiciones similares a las
de compareTo().
Los objetos que implementa la interfaz Comparator pueden ser utilizados en las siguientes
situaciones (especificando un orden distinto al natural):
Como argumento a un constructor TreeSet o TreeMap (con la idea de que las mantengan
ordenadas de acuerdo con dicho comparador).
En los métodos de ordenación Collections.sort(List, Comparator) y Arrays.sort(Object[],
Comparator).
En los métodos de búsqueda Collections.binarySearch(List, Object, Comparator) y
Arrays.binarySearch(List, Object, Comparator).
//ComparadorIgnoraMayMin
import java.util.*;
class ComparadorIgnoraMayMin implements Comparator {
public int compare(Object o1, Object o2) {
Persona p1 = (Persona)o1; //Eleva ClassCastException si o1 no es Persona
Persona p2 = (Persona)o2; //Eleva ClassCastException si o2 no es Persona
//Es igual que compareTo de Persona pero usando compareToIgnoreCase()
int cmp = p1.getApellidos().compareToIgnoreCase(p2.getApellidos());
if (cmp == 0){
cmp = p1.getNombre().compareToIgnoreCase(p2.getNombre());
if (cmp == 0){
cmp = p1.getEdad() - p2.getEdad();
}
}
return cmp;
}
}
// ComparadorEdad.java
import java.util.*;
// TestEmpleadoComparators.java
import java.util.*;
public class TestEmpleadoComparators{
public static void main(String args[]){
List c = new ArrayList();
Lista Original:
[Lopez Perez, Pepe (25), lopez Aguilar, Lola (23), Lopez Perez, Pepe (21), Lopez Perez,
Antonio (25), Sanchez Olmo, Alicia (21)]
Process Exit...
Usaremos Comparable para definir el orden natural de una clase C, entendiendo por orden
natural aquel que se utilizará normalmente o simplemente por convenio. Así, diremos que los
objetos de clase C son comparables.
Por otro lado, implementaremos nuevas clases (C1 … Cn) que extiendan el interfaz Comparator
por cada ordenación nueva que necesitemos distinta a la natural para la clase C. Así tendremos
una “librería de comparadores” (C1 … Cn) para la clase C.
Los más interesantes son los siguientes (todos los métodos aquí expuestos retornan o toman
como argumentos una List, excepto max y min que toman como argumento una Collection):
5.1. Ordenación
Ordenan la lista, bien de forma ascendente según el orden natural (establecido por el interfaz
Comparable), o bien de la forma especificada por Comparator. Tal ordenación es estable, es
decir, los elementos iguales no son desplazados. Lanzan las siguientes excepciones:
ClassCastException, si un elemento en la lista tiene un tipo que impide su comparación con el
resto los interfaces Comparable o Comparator; UnsupportedOperationException, si la lista no es
modificable (su iterator no soporta la operación set).
5.3. Búsqueda
Buscan el objeto en la lista y devuelven la posición (int) de tal objeto (resultado 0 o positivo). Si
no está en la lista devuelve (-(pos_mayor)-1); donde pos_mayor es la posición del primer
elemento en la lista mayor que el buscado, o el tamaño de la lista si el elemento buscado es el
mayor de todos.
La lista debe estar ordenada de forma ascendente. Esto puede lograrse con un orden natural
para el primer método, como por ejemplo sort(List); o bien usando un Comparator para el
segundo método: sort(List,Comparator). Los resultados no son especificados si la lista esta
desordenada. No se asegura cuál será el elemento devuelto si existen duplicados.
Lanzan la excepción ClassCastException si algún elemento en la lista tiene un tipo que impide
su comparación.
NOTA: Sobre el sentido de la ordenación impuesto por sort y el sentido en que esta ordenada
la lista o matriz que binarySearch examina, la API especifica que en estos dos métodos, tanto
en la clase Arrays como en la clase Collections, el sentido de la ordenación sea ascendente.
Esto es debido a que las clases que implementan Comparable o Comparator lo hacen en la
forma descrita en la API. Siguiendo estas recomendaciones los comparadores que creásemos
serían siempre ascendentes. Para lograr una ordenación inversa utilizaríamos el método
reverseOrder de la clase Collection. Alternativamente puede implementarse un Comparator o
Comparable descendente y utilizarse en ambos métodos. Luego, lo realmente importante es
mantener el sentido con el que se ha ordenado un contenedor a la hora de buscar en él. Es
conveniente también recordar que los tipos primitivos y sus envolturas implementan
Comparable en sentido ascendente.
Remplaza todos los elementos de la lista por el objeto especificado. No modifica el tamaño de la
lista. Se ejecuta en un tiempo lineal.
Lanza UnsupportedOperationException si el iterator de la lista no soporta la operación set.
5.7. Constantes
Existen tres constantes (campos estáticos finales) de tipo List y Set que son inicializados para
contener un objeto vacío del tipo correspondiente. Sus nombres son EMPTY_LIST y EMPTY_SET.
Sirven para representar contenedores vacíos.
Ejemplo:
import java.util.*;
//Máximo y mínimo
Empleado eMax = (Empleado) Collections.max(c, new ComparadorEdad());
Empleado eMin = (Empleado) Collections.min(c, new ComparadorEdad());
System.out.println("Empleado más viejo: " + eMax);
System.out.println("Empleado más joven: " + eMin);
}
}
Retorna una vista (no una copia) de la matriz pasada como argumento implícito, que puede ser
manipulada como si fuera una lista. Como dicha lista es respaldada por una matriz no pueden
agregarse o eliminarse elementos a ella. Cualquier modificación estructural (del número de
elementos) provoca UnsupportedOperationException debido a la no implementación de los
métodos opcionales del interfaz List en la lista retornada. El resto de cambios en la lista son
reflejados en la matriz y viceversa.
7 Clase java.lang.Math
La case Math del paquete estándar java.lang contiene métodos estáticos para realizar
operaciones matemáticas básicas como exponencial, logaritmos, raiz cuadrada, funciones
trigonométricas, etc. La invocación a tales métodos o constantes es similar a los de Collections
y Arrays: Math.metodo(<argumentos>)
double atan(double);
double toRadians(double);
double toDegrees(double);
// Funciones básicas
double exp(double);
double log(double);
double log10(double);
double sqrt(double);
double ceil(double);
double floor(double);
double pow(double, double);
<int/long/float/double> abs(<int/long/float/double>);
<int/long/float/double> max(<int/long/float/double>, <int/long/float/double>);
<int/long/float/double> max(<int/long/float/double>, <int/long/float/double>);
< . . . >
}
8 Bibliografía
• Documentación de la API de Java:
• Thinking in Java, 3rd Edition. Bruce Eckel. Prentice Hall, 2002. Capítulo 11.
http://www.mindview.net/Books/TIJ/