SlideShare una empresa de Scribd logo
1 de 46
Descargar para leer sin conexión
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones 1
TEMARIO DE CURSO
PROGRAMACIÓN JAVA SE
CAPÍTULO 11
COLECCIONES
© Iñaki Martín
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ En Java, los array son de tamaño fijo, una vez declarados y asignado un tamaño, éste no puede cambiarse.
๏ Para trabajar con estructuras de datos dinámicas, esto es, cuyo tamaño pueda variar, se usan Colecciones.
Colecciones : Conjunto de objetos, de tamaño dinámico.
๏ Para trabajar con colecciones, no se puede hacer con tipos primitivos (int, char, double…), solo con
objetos.
Por lo tanto, para trabajar con tipos parecidos a primitivos, podemos usar las clases envoltorios (por ejemplo,
no se puede usar int ni double, pero sí Integer o Double )
Definir Colecciones
Tipos de colecciones y definición
2
Desde Java 5 la conversión entre tipos primitivos y su clase envoltorio hace casting implícito,
(autoboxing, para poder asignar directamente un int a un Integer, y viceversa con autounboxing),
Con las clases envoltorio no es recomendable hacer operaciones matemáticas, pues hace una doble conversión interna
que es poco productiva (sumar dos Integer supone convertir internamente ambos a int, operar, y convertir a Integer el
resultado)
Sin embargo, las clases envoltorio con claramente útiles cuando se trata de almacenamiento en colecciones
๏ Las clases de colección están en el paquete java.util, y son herencias todas de una interfaz madre
๏ Los tipos más importantes de colecciones son:
‣ Listas clases : ArrayList, Vector, LinkedList ( subclases de interfaz List )
‣ Mapas clases : HashMap, TreeMap ( subclases de interfaz Map y Table )
‣ Conjuntos clases : HashSet, TreeSet ( subclases de interfaz Set )
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Diagrama de colecciones
Diagrama de clases de colecciones
๏ Esta es una clasificación de las clases más importantes en relación a las colecciones Java
๏ Advertir que de la clase Collections solo heredan List y Set, no así en el caso de Map
Leyenda
3
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Resumen de colecciones
Resumen tipos colecciones
4
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Una lista es una colección que almacena los elementos junto con un identificador numérico asociado a cada uno
๏ Las características de una Lista son:
‣ El indicador (indice) es un entero creciente, muy parecido al de un array
‣ Es de tamaño variable, no fijo como un array
‣ Se puede acceder a los elementos (leer, añadir o borrar) por su posición a través del índice.
‣ Puede contener elementos duplicados
‣ List es la interfaz de la que cuelgan el resto de colecciones de lista; ArrayList, LinkedList, Vector, etc.
‣ Para construir una lista, se puede usar una clase "hija" de List
aunque normalmente se suele usar con polimorfismo (ambas son perfectamente válidas):
En este segundo caso, se aplica upcasting
Colecciones de tipo Lista
Listas
5
CLASELISTA<String> laLista2 = new CLASELISTA<String>();
List<String> laLista2 = new CLASELISTA<String>();
Sustituir CLASELISTA por una
de las clases de tipo lista
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Métodos básicos de tipo Lista 6
CLASE DEVUELVE METODO DESCRIPCION
List boolean add (Object 0b) Mete un elemento al final de la lista
List void add (int pos, Object elem) Mete un elemento en la posición indicada, moviendo el resto hacia adelante
List Object get (int pos) Devuelve el elemento de la posición pos. Cuidado: devuelve Object si ArrayList si no tiene tipo.
List object remove (int posicion) Elimina el elemento de la posición indicada. Devuelve dicho elemento.
List int indexOf (Object ob) Devuelve el indice de la primera ocurrencia del objeto ob en la lista, o -1 si no lo encuentra
List Object set (pos, elemento) Sustituye el elemento de la posición pos. Devuelve error si la posicion no existe
List void clear() Elimina los elementos de la lista
List boolean contains(Object ob) Informa de si un determinado contenido está en la colección. Cuidado: contains usa equals() para
comparar, si se usan clases propias, es necesario sobreescribir equals()
List int size () Devuelve el numero de elementos que tiene la
objLista.add("Ejemplo"); // Suponiendo que la lista contenga Strings
objLista.clear();
boolean existe = objLista.contains("Ejemplo"); // Suponiendo una lista de Strings
int pos = objLista.indexOf("Ejemplo"); // Suponiendo que la lista contenga Strings
objLista.remove(0);
String res = objLista.get(0);
objLista.add( 3, "Ejemplo"); // Suponiendo que la lista contenga Strings
objLista.set( 1, "Otro Ejemplo"); // Suponiendo que la lista contenga Strings
int tamano = objLista.size(); // Suponiendo una lista de Strings
Métodos más importantes de LIST (Y de todas sus clases heredadas)
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Otros métodos de tipo Lista 7
CLASE DEVUELVE METODO DESCRIPCION
List boolean addAll(Collection cole) Mete todos los elementos de la coleccion cole al final de la lista. Añade los nuevos elementos, aunque ya estuvieran en la coleccion
inicial, con lo que pueden aparecer repetidos
List boolean remove (Object ob)) Elimina (la primera ocurrencia) del objeto parametro. Devuelve true si pudo eliminarlo
List int lastIndexOf(Object obj) Devuelve el indice de la última ocurrencia del objeto parámetro dentro del objeto invocante. Devuelve -1 si no encuentra el objeto
en la colección
List List subList(int start, int end) Devuelve una lista sacando los elementos desde el indice start al índice end (“shallow” copy)
List object toArray() Convierte un ArrayList en un array de Object, que necesitan casting posterior:
Si no se desea usar el casting, hay otra forma de usar toArray() algo compleja:
• El método toArray() debe recibir un parámetro que ha de ser un array para que lo llene, array del mismo tipo que la coleccion.
• El array puede estar vacío, pero ha de estar creado y con tamaño suficiente.
• Devuelve un array del mismo tipo que el la coleccion (que no es obligatorio usar)
Si el array que se crea con toArray() no tiene el tamaño mínimo, se crea un nuevo array en tiempo de ejecución para almacenar el
numero necesario de elementos. En este caso, el array que se modifica no es el que se pasa por parámetro, que queda a null, sino
el que se devuelve por el método, igual que en el primer uso del método explicado mas arriba
ArrayList<String> lista2 = new ArrayList<>();
lista2.add("Juan");
lista2.add("Pedro");
String [] nombres2 = (String []) objLista.toArray();
ArrayList<String> lista8 = new ArrayList<>();
lista2.add("Juan");
lista2.add("Pedro");
String[] nombres8 = new String[2];
nombres2 = objLista.toArray(nombres2);
ArrayList<String> lista2 = new ArrayList<>();
lista2.add("Juan");
lista2.add("Pedro");
String[] nombres2 = new String[1];
String[] nombres3 = objLista.toArray(nombres2);
Otros métodos menos importantes de LIST
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Listas: ArrayList
๏ El objeto se crea:
๏ Desde JEE7 existe inferencia de tipos, que nos evita indicar nuevamente el tipo:
ArrayList (hereda de List)
8
// ArrayList<tipo> variable = new ArrayList<tipo>();
ArrayList<String> laLista2 = new ArrayList<String>();
Un ArrayList es un tipo genérico, que se identifica por que al crear un objeto se debe indicar el tipo del dato que
almacenará
ArrayList<tipo> variable = new ArrayList<tipo>();
Si no se indica, se está creando igualmente un ArrayList, pero sin tipo asociado, esto es, se puede almacenar
cualquier cosa dentro (de hecho, se almacenan objetos de tipo Object)
ArrayList variable = new ArrayList();
A estos tipos construidos sin especificar genérico, se le denomina raw types.
Los raw types, lejos de una ventaja, es un inconveniente pues nunca se sabe con certeza que tipo tiene cada
elemento, con lo que
- a la hora de extraer los elementos, hay que extraerlos como Object, y hacer un casting a lo que se quiera
- Hay que adivinar hacia qué tipo de dato se desea hacer el casting....
Por lo tanto es mejor declarar siempre el tipo del dato de la colección, salvo que se desee explícitamente por alguna razón usar tipos raw
Todo esto aplica a los ArrayList y a todas las Listas, Mapas o Conjuntos, explicados más adelante
Consultar el capítulo que trata de Genéricos para ahondar en estos conceptos
CLASE DEVUELVE METODO DESCRIPCION
ArrayList Object clone () Devuelve una “shallow copy” (superficial) de la
coleccion actual
ArrayList void removeRange (int inicio, inf fin) Borra los elementos de la lista que se encuentren
entre inicio (inclusive) y finn (exclusive)
Métodos exclusivos de ArrayList
(aunque los más importantes son los heredados de
List)
// ArrayList<tipo> variable = new ArrayList<>();
ArrayList<String> laLista2 = new ArrayList<>();
• La inferencia también aplica al resto de
colecciones
• Al <> se le llama, a veces, operador
“diamante"
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Muy parecida a ArrayList, con métodos casi
iguales, pero tiene peor rendimiento que
ArrayList.
๏ Es beneficioso su uso en proyectos multitarea,
pues sus métodos están sincronizados.
Esto perjudica el rendimiento, por lo que solo es
interesante si se necesita utilizar multitarea.
๏ Además, permite definir un numero mínimo de
elementos y gestionar el tamaño del
almacenamiento
Vector (hereda de List)
๏ Con metodos casi iguales que ArrayList, pero
preparada para trabajar en modo pila o cola
(con métodos para acceder y retirar
elementos desde la cabeza o la cola de la
coleccion)
LinkedList (hereda de List)
9
CLASE DEVUELVE METODO DESCRIPCION
LinkedList void addFirst (Object ob) Inserta el objeto ob al principio de la lista, desplazano los
demas
LinkedList void addLast (Object ob) Inserta el objeto ob al final de la lista
LinkedList void descendingIterator () Devuelve un Iterator de los elementos en orden inverso
LinkedList Object getFirst () Devuelve, sin eliminarlo, el primer elemento de la lista
LinkedList Object getLast () Devuelve, sin eliminarlo, el ultimo elemento de la lista
LinkedList Object peek () Devuelve, sin eliminarlo, el primer elemento de la lista
LinkedList Object poll () Devuelve, y además elimina, el primer elemento de la lista
LinkedList Object removeFirst () Devuelve, y además elimina, el primer elemento de la lista
LinkedList Object removeLast () Devuelve, y además elimina, el ultimo elemento de la lista
CLASE DEVUELVE METODO DESCRIPCION
Vector boolean copyInto ( Object [] unarray) Copia los elementos del vector en el array
Vector void ensureCapacity( int capacidad) Incrementa la capacidad del vector si es necesario, hasta
asegurar que puede almacenar el numero minimo de
elementos especificados por el atributo Capacidad Minima
(se puede definr en el constructor)
๏ El objeto se crea: Vector<tipo> variable = new Vector<tipo>();
๏ El objeto se crea: LinkedList<tipo> variable = new LinkedList<tipo>();
Métodos exclusivos de Vector
(aunque los más importantes son los heredados de List)
Métodos exclusivos de LinkedList
(aunque los más importantes son los heredados de List)
Listas: Vector y LinkedList
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Recorriendo colecciones con For-each
๏ Desde java5 existe una variante de for(), llamada FOR EACH
Usa una variable interna de control para recorrer una colección (array, List o cualquier otra)
๏ Su formato es el siguiente ;
for (tipoDeCadaDatoDeLaColeccion unaVariable : coleccionARecorrer) {
x = unaVariable;
}
๏ Viene a hacer algo así como “Coge la colección puesta a la derecha de los dos puntos, y para cada vuelta
del bucle, vas sacando un elemento y lo metes en la variable que se declara a la izquierda de los dos
puntos”
๏ Así pues, unaVariable va pasando por cada uno de los elementos del array o de la colección que sea.
๏ Si la colección tiene un índice (como los arrays o los ArrayList) los elementos se van sacando en el orden del
indice
๏ Solo se puede usar para lectura de los valores, ¡¡ no para asignación ni borrado de los mismos !!
๏ Tambien se puede usar for-each con un array
For-Each (for avanzado)
10
for (int i=0; i< laLista.size (); i++) {
System.out.println (laLista.get(i));
}
for (Integer unnum : laLista) {
System.out.println (unnum);
}
for (Persona per : laLista) {
System.out.println (per.nombre);
}
๏ Ejemplo de como se recorre una
colección con un bucle for
tradicional, y como se hacer con un
for-each, tanto con tipos wrappers
como con objetos
(laLista representa la colección a recorrer)
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ En estas clases los objetos no tienen un índice numérico, sino que tienen un índice popio, que se añade
junto al propio dato a almacenar en la colección.
๏ Este índice se llama clave, y hace las funciones de índice, pero no ordenado.
๏ La información que se almacena se denomina valor
๏ Las características de un Mapa son:
Colecciones de tipo MAPA o TABLA
Mapas
11
‣ La clave puede ser de cualquier tipo de objeto, no
tipo primitivo (al igual que pasa con el valor)
‣ Es de tamaño variable, no fijo como un array
‣ Al crear el mapa, se debe indicar el tipo de la clave,
y el tipo del valor almacenado en el mapa
‣ Se puede acceder a los elementos (leer, añadir o borrar) por su posición a través del índice.
‣ No puede contener elementos con la clave duplicada
‣ Map es la interfaz de la que cuelgan el resto de colecciones de mapas; HashMap, TreeMap, etc.
‣ Para construir una lista, se puede usar una clase "hija" de Map
aunque normalmente se suele usar con polimorfismo (ambas son perfectamente válidas):
CLASEMAPA<Integer, String> elMapa2 = new CLASEMAPA<>();
Map<Integer, String> elMapa2 = new CLASEMAPA<>();
Sustituir CLASEMAPA por una
de las clases de tipo mapa
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
CLASE DEVUELVE METODO DESCRIPCION
Map int size () Devuelve el tamaño de la colección.
Map object remove(ind) Elimina el elemento con el indice “ind”. Devuelve null si no existe el indice
Map void clear() Elimina todos los elementos de la colección
Map boolean containsKey (Object clave) Indica si existe esa clave en la colección
Map boolean containsValue (Object valor) Indica si existe ese objeto-valor entre los valores de la colección
Map object get (Object indice) Devuelve el valor asociado con el indice indicado por parámetro, o null si no existe el indice
Map object put (Object clave, Object valor) Coloca una clave y valor en la coleccion. Si la clave ya existían se sobrescribe el antiguo valor.
Devuelve el antiguo valor, si ya existía la clave, o null si no existía la clave
Map Collection
values() Devuelve una colección conteniendo únicamente los objeto-valor del mapa.
Map Set
keySet() Devuelve un conjunto (Set) conteniendo únicamente las objeto-clave del mapa.
Map boolean
isEmpty() Indica si la colección esta vacía
Map Set
entrySet() Devuelve un conjunto de elementos llamados Map.Entry, que son precisamente del mismo “tipo”
que el mapa (esto es, el par de elementos clave-valor) (ver mas adelante ejemplos y detalle)
12
objMapa.size();
objMapa.remove( 32 ); // Suponiendo que el Mapa tenga Integer en la clave
String elValor = objMapa.get(63); // Suponiendo que el mapa contenga Strings
boolean existeLaClave = objMapa.containsKey(14);
objMapa.clear();
objMapa.put( 19, "Juan"); // Suponiendo que el Mapa tenga Integer y String
boolean existeElValor = objMapa.containsValue("Pepe");
ArrayList<String> v = objMapa.values();
TreeSet<Integer> v = objMapa.keys();
boolean estaVacioElMapa = objMapa.isEmpty();
Métodos más importantes de MAP (Y de todas sus clases heredadas)
Métodos básicos de tipo MAP
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
• Un objeto TreeMap se crea igual que
cualquier otro mapa
• Un TreeMap garantiza que los elementos del
mismo están ordenados ascendentemente por
la clave.
La clave se ordena ascendentemente (si permite un orden
natural de ordenación) o si se trata de una clase, según la
implementación de Comparator que tenga (ver mas
adelante)
• Tiene muchos métodos además de los que
sobrescrito de Map
Mapas: TreeMap y HashMap
TreeMap (de tipo Map)
• Un objeto HashMap se crea igual que cualquier
otro mapa
• En el ejemplo, el Integer hace referencia al
índice, mientras que el contenido de la tabla es
un String
• En un HashMap, no se puede garantizar el
orden de los elementos, de hecho, puede variar
durante la propia ejecución.
• En un HashMap se permite que sea null tanto la
clave como el valor.
HashMap (de tipo Map)
13
CLASE DEVUELVE METODO DESCRIPCION
HashMap Set clone() Devuelve una copia del map.
Métodos exclusivos de HashMap
(aunque los más importantes son los heredados de Map)
CLASE DEVUELVE METODO DESCRIPCION
TreeMap object
ceilingEntry(clave
)
Devuelve el valor asociado a la siguiente clave superior o igual en el
orden a la pasada por parámetro, o null si no existe
TreeMap object
ceilingKey (clave) Devuelve la siguiente clave superior o igual en el orden a la pasada por
parámetro, o null si no existe
TreeMap object
floorEntry(clave) Devuelve el valor asociado a la siguiente clave inferior o igual en el
orden a la pasada por parámetro, o null si no existe
TreeMap object
floorKey(clave) Devuelve la siguiente clave inferior o igual en el orden a la pasada por
parámetro, o null si no existe
TreeMap Set entrySet() Devuelve como un conjunto (set) los valores de la colección.
TreeMap object
firstEntry() Devuelve, tomando los elementos ordenados, el valor del elemento de
clave mas baja.
TreeMap object
firstKey() Devuelve, tomando los elementos ordenados, la clave mas baja
(primera clave).
TreeMap object
lastEntry() Devuelve, tomando los elementos ordenados, el valor del elemento de
clave mas alta
TreeMap object lastKey() Devuelve, con los elementos ordenados, la clave mas alta (ultima clave).
Métodos exclusivos de TreeMap
(aunque los más importantes son los heredados de Map)
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Al intentar usar un for-each con un mapa, se verá que no funciona recorriendo el mapa...¿por que?
๏ Un Mapa internamente guarda dos colecciones (los indices y los valores). Al recorrer con un for-each, hay que decirle a
éste cuál de las dos colecciones ha de recorrer, si la de las claves o la de los valores
๏ Por lo tanto, no se puede recorrer directamente un mapa, hay que crear una colección intermedia de claves o de valores
๏ Esta coleccion intermedia ha de ser del tipo Collection, que es superclase de Listas y Conjuntos, con este uso:
✴ con el método .values() se consigue una colección con los valores del mapa. La coleccion es de la clase Collection
Ya vimos que este método devuelve un objeto de tipo Collection con la colección de valores del mapa, que sí tiene un indice para poder usarse en un for-each
✴ con el método .keySet() se consigue una colección con los índices del mapa
Ya vimos que este método devuelve un objeto de tipo Set (hija de Collection) con la colección de valores del mapa, que sí tiene un indice para poder usarse en un for-each
๏ Ejemplo: Partimos de este mapa ya creado:
Recorriendo un Map
¿ Como recorrer un Map?
14
Map<Integer,String> miMapa = new HashMap<>();
miMapa.put(29,"Ana");
miMapa.put(17,"Mercedes");
miMapa.put(31,"Maria");
// Creando un objeto Collection y usándolo en for-each
Collection<String> losvalores = miMapa.values();
for (String cadavalor : losvalores) {
System.out.println(cadavalor);
}
// Usando en el for-each directamente el método values()
for (String cadavalor : miMapa.values()) {
System.out.println(cadavalor);
}
✦ Recorriendo los valores: usando .values()
// Creando un objeto Collection y usándolo en for-each
Collection<Integer> lasclaves = miMapa.keySet();
for (Integer cadaclave : lasclaves) {
System.out.println(cadaclave);
}
// Usando en el for-each directamente el método keySet()
for (Integer cadaclave : miMapa.keySet()) {
System.out.println(cadaclave);
}
✦ Recorriendo las claves: usando .keySet()
consola
Ana
Mercedes
Maria
consola
29
17
31
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Ya se ha visto que de un mapa o se recorre la colección de valores o la de claves
๏ Pero, ¿y si quiero recorrer ambas colecciones a la vez? (conocer en un mismo bucle los valores y sus claves)
๏ Una solución es recorrer en un bucle las claves, y dentro del bucle, ir sacando los valores:
๏ Pero hay una solución que aporta java, más efectiva, usar el método entrySet() en el mapa. Así se usa:
MapEntry 15
for (Integer cadaclave : miMapa.keySet()) {
String cadavalor = miMapa.get(cadaclave);
System.out.print(cadavalor);
System.out.println(cadaclave);
}
- entrySet() en un mapa devuelve un conjunto de elementos llamados Map.Entry .
- Cada Map.Entry es realmente un par de elementos (clave y valor), correspondiente a cualquier elemento del Mapa
- De cada elemento del Map.Entry se puede extraer el valor con el método getValue() y la clave con el método getKey()
๏ Ejemplo: Analicemos como funciona Map.Entry, viendo los métodos necesarios al usarlo dentro de for-each;
‣ En la colección a recorrer, usar entrySet() en el mapa a recorrer
‣ En el elemento que entrega el for-each, poner como tipo Map.Entry<tipoClave, tipoValor>
‣ En el interior del for-each, usar con cada elemento getValue() (para valores) y getKey() (para claves):
// En este caso es siempre mejor usar el método entrySet directamente dentro del for-each
for (Map.Entry<Integer, String> cadaEntry : miMapa.entrySet() ) {
System.out.println ("clave = " + cadaEntry.getKey() + ", valor = " + cadaEntry.getValue());
}
MapEntry
consola
Ana29
Mercedes17
Maria31
consola
Clave = 20, valor = Ana
Clave = 10, valor = Mercedes
Clave = 30, valor = Maria
Map<Integer,String> miMapa = new HashMap<>();
miMapa.put(29,"Ana");
miMapa.put(17,"Mercedes");
miMapa.put(31,"Maria");
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
• Los Set (conjuntos) son las colecciones más simples, pues agrupan objetos sin clave ni índice.
• Sus principales características son:
✴ No existen métodos para recuperar un valor, pues no hay modo de identificarlos al no tener índice ni clave.
✴ Lo que sí que se puede es recorrer directamente con un for-each.
✴ No puede tener elementos duplicados, claro.
✴ Esta clase se usa por lo tanto solo para agrupar, y recorrer, pero no para recuperar nada específico
✴ Set es la interfaz de la que cuelgan el resto de colecciones de lista; HashSet, TreeSet, LinkedHashSet.
Colecciones tipo SET (Conjunto)
Set
16
CLASECONJUNTO<Integer, String> elMapa2 = new CLASECONJUNTO<>();
Set<Integer, String> elMapa2 = new CLASECONJUNTO<>();
Sustituir CLASECONJUNTO por
una de las clases de tipo mapa
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones 17
CLASE DEVUELVE METODO DESCRIPCION
Set boolean add (Object obj) Añade un objeto a la colección. Si añadimos un elemento igual a uno existente,
devuelve False y no hace nada. Si no existe, lo añade y devuelve True.
Set int size () Devuelve el tamaño de la colección.
Set object remove (Object obj) Elimina el elemento que contiene el valor indicado. Devuelve null si no existe el
elemento
Set boolean contains(Object obj) Informa de si un determinado contenido esta en la colección
Set void clear() Elimina todos los elementos de la colección
Set boolean isEmpty() Indica si la colección esta vacía
Set Object [] toArray() Convierte un Set en un array de Object, que necesitan casting posterior.
(Ver ejemplo en el caso de List)
Set int addAll(Collection cole) Mete todos los elementos de la coleccion cole al final del conjunto
Si hay elementos que ya existen en la coleccion origen, los sustituye
Los elementos nuevos, los incorpora al conjunto
objSet.add("Eva"); // Suponiendo que el Set contenga Strings
objSet.size();
objSet.remove("Juan); // Suponiendo que el Set contenga Strings
boolean existe = objSet.contains("Ana"); // Suponiendo un Set de Strings
objMapa.clear();
boolean estaVacio = objSet.isEmpty("Ana"); // Suponiendo un Set de Strings
Métodos más importantes de SET (Y de todas sus clases heredadas)
Métodos básicos de tipo SET
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
• Ordena los elementos en base al valor de su
contenido (sea orden natural o por Comparator/
Comparable)
• Ofrece peor rendimiento que otras clases
• Un objeto TreeSet se crea igual que cualquier otro
conjunto
TreeSet (de tipo Set)
• Ofrece el mejor rendimiento de todas las clases
conjunto
• No da ninguna garantía de como se ordenan los
elementos ni en que orden se extraen
• Permite elementos nulos
• Un objeto TreeSet secrea igual que cualquier otro
conjunto
HashSet (de tipo Set)
• Ofrece un rendimiento casi igual a HashSet
• Ordena los elementos por el orden en que fueron
añadidos a la coleccion
LinkedHashSet (de tipo Set)
18
CLASE DEVUELVE METODO DESCRIPCION
TreeSet Set clone() Devuelve una copia de la colección
TreeSet object
ceiling (Object
obj)
Devuelve el valor superior o igual en orden al dado por parámetro, o null
si no existe
TreeSet object floor (Object obj)
Devuelve el valor inferior o igual en orden al dado por parámetro, o null
si no existe
TreeSet object first()
Devuelve, tomando los elementos ordenados, el valor mas bajo (primer
valor).
TreeSet object last()
Devuelve, tomando los elementos ordenados, el valor mas alto (ultimo
valor).
TreeSet Set
headSet (Object
obj)
Devuelve en un conjunto (set) los valores de la colección menores o
iguales al parámetro
TreeSet Set
tailSet (Object
obj)
Devuelve en un conjunto (set) los valores de la colección mayores o
iguales al parámetro
TreeSet Set
subSet(int
fromIndex, int
toIndex)
Devuelve el conjunto de elementos que se encuentran entre los índices
indicados en los parámetros, desde el primer parámetro inclusive al
segundo parámetro exclusive
CLASE DEVUELVE METODO DESCRIPCION
HashSet Set clone() Devuelve una copia de la colección
Métodos exclusivos de TreeSet(aunque los más
importantes son los heredados de Set)
Métodos exclusivos de HashSet
(aunque los más importantes son los heredados de Set)
Set: TreeMap y HashMap
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Clase Collections 19
๏ Collections es la calse de la que heredan todos las clases de Listas y Conjuntos (los Mapas van por otras ramas)
๏ La clase ofrece muchos métodos que puede usar cualquier Lista o Conjunto
๏ Los métodos son todos static, con lo que se invocan con Collections directamente
๏ Si han de modificar una colección, la suelen recibir como argumento y la modifican directamente (no devuelven lo modificado)
Métodos más importantes de COLLECTIONS (todos ellos STATIC)
CLASE DEVUELVE METODOS (TODOS STATIC) DESCRIPCION
Collections
boolean addAll(Coleccion a, val1,val2,...) Añade a la coleccion indicada como priemr parámetro los elementos indicados como segundo y
sucesivos parámetros
Collections
int binarySearch(Lista lis, objeto obj) Devuelve el índice del elemento obj, buscado dentro de la lista lis. Devuelve un número negativo si no
encuentra el elemento. Solo vale para Listas. Realiza un búsqueda binaria.
Collections
int binarySearch(Lista lis, objeto obj,
Comparator com)
Devuelve el índice del elemento obj, buscado dentro de la lista lis. Devuelve un número negativo si no
encuentra el elemento. Utililza el objeto Comparator comp para la búsqueda, que es búsqueda
binaria.
Collections void copy(Lista destino, lista origen) Copia los elementos de la lista origen en la lista destino. Solo vale con Listas. Duplica si hay repetidos
Collections boolean disjoint(Coleccion c1, Coleccion c2) Devuevlve true si las colecciones espeficicadas no tienen elementos en comun
Collections void fil(Lista lis1, objeto obj) Reemplaza en la lista lis1 todos los elementos con el elemento obj. Solo vale para Listas
Collections int frequency(Coleccion col1, objeto obj) Devuelve el número de veces que el objeto obj se encuentra en la coleccion col1
Collections
void reverse(Lista lis1) Invierte el orden de los elementos de la lista lis1 (el ultimo es el primero, penultimo segundo...) Solo
vale para Listas
Collections void rotate (Lista lis1, int desplaz) Rota los elementos de las lista lis1 tantas posiciones como desplaz indique. Solo vale para Listas
Collections void shuffle (Lista lis1) Desordena aleatoriamente la lista lis1. Solo vale para Listas
Collections void sort (Lista lis1) Ordena la lista lis1 ascendentemente, de acuerdo con su ordena natural. Solo vale para Listas
Collections
void sort (Lista lis1, Comparator comp) Ordena la lista lis1 ascendentemente, de acuerdo con el orden aplicado por la el objeto comp. Solo
vale para Listas
Collections
void swap( Lista lis1, int posx, int posy) Intercambia los valores de los elementos de indices posx y posy, dentro de la lista lis1. Solo vale para
Listas
Clase Collections
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Iterator ofrece métodos que permiten recorrer las colecciones con mejoras sobre un simple for o for-each.
๏ Todos los objetos de tipo colección implementan la interfaz Iterator.
๏ En particular, los borrados de elementos de una colección no se deben hacer con un for-each, pues puede
fallar.
Cuando se hace un for-each, java crea una copia ordenada de los elementos. Si se intenta eliminar elementos dentro del for-each, java se queja de que la copia
que tenia previamente preparada puede quedar inconsistente, y da un ConcurrentModificationException
Iterator
Iterator
20
for (String nombre : lista2) {
if (nombre.equals("Pedro")) {
lista2.remove("Pedro");
}
}
๏ Si se ejecuta este bucle puede producir un error como este :
consola
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
En purismo, no se produce el error si sólo se efectua un remove dentro del for-each. El error se da si se efectuan dos o mas remove.
Pero por control de errores en todas situaciones, no se debe usar un for-each para un borrado. Siempre es mejor usar iterator
๏ Para usar Iterator se aplica el método iterator() a una colección, y esto devuelve un objeto de tipo Iterator :
Iterator objetoIterator = miColeccion.iterator();
๏ Con dicho objeto que se pueden usar los siguientes métodos:
CLASE DEVUELVE METODO DESCRIPCION
Iterator boolean hasNext() Indica si hay más elementos a devolver de la lista, pero no devuelve
ni coge ninguno
Iterator object next() Devuelve el siguiente elemento de la lista, y avanza el puntero de la
misma para que el próximo next() apunte al siguiente elemento. La
lista inicialmente apunta al primer elemento.
Da excepción NoSuchElementException si no hay elemento que leer
Iterator object remove() Borra el elemento actual de la lista (el último recogido con una
instrucción next() )
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Si la colección es de tipo Lista, se puede usar ListIterator, que tiene más métodos que Iterator (hasPrevious( ), previous(), add(), set(),
prevoiusIndex(), nextndex(), etc)
Interfaz ListIteratorTemas avanzados
• El uso de Iterator es muy sencillo. Se aplica el método iterator() a una colección, y esto devuelve un objeto
de tipo Iterator :
Iterator objetoIterator = unaColeccion.iterator();
• Con dicho objeto que se pueden usar los siguientes métodos:
Iterator (II) 21
CLASE DEVUELVE METODOS (TODOS STATIC) DESCRIPCION
Iterator boolean hasNext() Indica si hay más elementos a devolver de la lista, pero no devuelve ni coge ninguno
Iterator
object next() Devuelve el siguiente elemento de la lista, y avanza el puntero de la misma para que el
próximo next() apunte al siguiente elemento. La lista inicialmente apunta al primer elemento.
Da la excepción NoSuchElementException si no hay elemento que leer
Iterator object remove() Borra el elemento actual de la lista (el último que se ha recogido con una instrucción next() )
CLASE DEVUELVE METODO DESCRIPCION
ListIterator boolean hasPrevious() Indica, sin devolver, si hay elementos antes del actual
ListIterator object previous() Devuelve el elemento previo al actual, y retrocede el puntero de recorrido de la colección
ListIterator object add (object) Añade el objeto parámetro antes del elemento actual (el último que se ha recogido con una instrucción next() o previous() ).
ListIterator object set( objeto) Sustituye el elemento actual por el pasado por parametro,
ListIterator int nextIndex() Devuelve el indice del siguiente elemento
ListIterator int previousIndex() Devuelve el indice del anterior elemento
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Iterator (III)
Ejemplos con Iterator (I)
• Iterator se puede usar sin definir el tipo de dato a ordenar, o definiéndolo (como tipo genérico)
• Se puede usar ListIterator para ordenar una lista al revés o con otras funcionalidad
22
// Creamos un ArrayList y algunos elementos para el
ArrayList<String> miArrayList = new ArrayList<>();
miArrayList.add("HOLA");
miArrayList.add("ADIOS");
miArrayList.add("BUENAS");
miArrayList.add("HELLO");
miArrayList.add("CIAO");
// Listamos el contenido con un ITERATOR SIN TIPO
Iterator iter = miArrayList.iterator();
while (iter.hasNext()) {
String unElemento = (String) iter.next(); // necesita casting pues no se sabe el tipo
System.out.println(" -> " + unElemento);
}
// Listamos el contenido con un ITERATOR CON TIPO GENERICO
Iterator<String> iter2 = miArrayList.iterator();
while (iter.hasNext()) {
String unElemento = iter2.next(); // ya no necesita casting
System.out.println(" -> " + unElemento);
}
// Cambiamos los valores del ArrayList según los leemos
// Podemos usar LISTITERATOR al ser un ArrayList la colección inicial
ListIterator<String> liter = miArrayList.listIterator();
while (liter.hasNext()) {
String unElemento = liter.next();
liter.set(unElemento + " con esto de apellido");
}
// Tratandose de un LISTITERATOR, tengo métodos para recorrer LA LISTA AL REVES
ListIterator<String> liter2 = miArrayList.listIterator();
while (liter2.hasPrevious()) {
Object element = liter2.previous();
System.out.print(element + " ");
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Iterator (IV) 23
/ Sin embargo, no puedo borrar elementos con un for-each, esto DA ERROR, ConcurrentModificationException
// for (String st : miArrayList) {
// miArrayList.remove(st);
// }
// Aunque si solo quiero borrar un elemento, sí puede hacerse con for-each,
// siempre que abandone el bucle tras borrar
System.out.println("El array tiene antes de borrar " + miArrayList.size() + " elementos");
int kk = 0;
for (String st : miArrayList) {
if (st.equals("HELLO con esto de apellido")) {
miArrayList.remove(st);
break; // ya se sabe que usar breaks... no es de lo más elegante
}
}
System.out.println("El array tiene ahora " + miArrayList.size() + " elementos");
// ASI QUE LA MANERA MÁS CORRECTA de eliminar elementos es usando Iterator. Aqui ejemplo con un ArrayList
Iterator<String> ite8 = miArrayList.iterator();
while (ite8.hasNext()) {
ite8.next();
ite8.remove();
}
System.out.println("El array tiene ahora " + miArrayList.size() + " elementos");
// Y aqui ejemplo con un Map. Primero creamos el hashMap
HashMap<Integer, String> miMapa = new HashMap<>();
miMapa.put(10, "Ana");
miMapa.put(20, "Mercedes");
miMapa.put(30, "Maria");
// Vemos primero que con for-each nos da error nuevamente por ConcurrentModificationException, esto NO vale
// Set<Integer> lasClaves = miMapa.keySet();
// for (Integer jk : lasClaves) {
// System.out.println("Borrando " + miMapa.get(jk));
// miMapa.remove(jk);
// }
// pero no da error con iterator
Set<Integer> lasClaves = miMapa.keySet();
Iterator<Integer> ite4 = lasClaves.iterator();
while (ite4.hasNext()) {
ite4.next();
ite4.remove();
}
System.out.println("El mapa tiene ahora " + miMapa.size() + " elementos");
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Cuidado con TreeSet y Comparator/Comparable
Ordenación de colecciones
Ordenación natural
๏ Se han visto varios tipos de colecciones de datos, ademas de los arrays. Contienen información, pero ¿pueden
ordenarse los datos de estas colecciones? ¿Puedo ordenar los datos a mi interés?
๏ Para poder ordenar elementos, la JVM ha de poder comparar dos elementos entre si para determinar cual es
mayor de los dos, y cual menor.
๏ Esta comparación puede hacerse de modo automático, depende del tipo de dato que se quiera ordenar:
Tipos de datos con ordenación natural: Tipos que se pueden ordenar por un orden natural, como el que
se da en los números o cadenas de texto (que se ordenan numéricamente o alfabéticamente, como los
String o los int). También se incluyen aquí Date y otras clases donde Java aplica orden por defecto.
Tipos de datos sin ordenación natural: Si se trata de un tipo de dato creado por nosotros, como una
Persona, una Tarjeta, un Coche, y se le pide a la JVM que la ordene, ¿que criterio ha de seguir?
Si le pido que ordene coches, ¿como lo ha de hacer? ¿por matricula? ¿por cilindrada? ¿por precio?
Estos tipos de datos necesitan que se defina programáticamente como se van a ordenar
24
• Un TreeSet tiene sus elementos ordenados…
¡ pero necesita poder ordenarlos !
• Si son de tipo de dato con orden natural, como int, funciona
sin más, pero como añadamos objetos a un TreeSet,
HEMOS de decirle con un Comparator o Comparable cómo
debe ordenar los objetos !!
• El ejemplo de la derecha falla, por que no sabe como ordenar
objetos de tipo Humano,
• Mas adelante en el capitulo de Comparable y Comparator
se da solución a este problema
public class EjemploComparator {
public static void main (String[] args) {
Set<Humano> p = new TreeSet<> ();
p.add (new Humano ("Luis", “Ruiz")); //ERROR
}
}
class Humano {
private String nombre;
private String apellido;
public Humano (String nombre, String apellido) {
this.nombre = nombre;
this.apellido = apellido;
}
}
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Ordenación de colecciones: mecanismos
Mecanismos de ordenación disponibles
๏ Ya se ha visto que si no se puede usar el mecanismo de ordenación natural, se debe acudir a usar las interfaces
Comparator y Comparable para crear una ordenación propia. Veamos a continuación su uso.
25
1. Usar algoritmos propios de ordenación, que aplicados a arrays o colecciones, reubica los
elementos de éstas según los criterios deseados. Uno de los ejemplos mas famosos es el
algoritmo de la burbuja.
Se explican algunos de estos algoritmos en las páginas de apéndices avanzados, al final del tema, pero no se detallan por ser
algoritmos de diferente definición y paralelos a los contenidos del lenguaje Java.
๏ A la hora de ordenar colecciones, podemos actuar con alguna de estas soluciones :
2. Usando el método sort() de ordenación (en las clases Arrays y Collections). Este método
funciona si:
a) Si tipo de dato a ordenar puede usar un mecanismo natural que de ordenación, sólo
hace falta usar el método sort() en la colección (tipos de datos primitivos, String, Date, etc)
b) Si el tipo de dato a ordenar es un objeto sin orden natural, se debe usar Comparator y
Comparable Ver más adelante
3. Usando el mecanismo de ordenación que por defecto traen alguna de las colecciones
(como TreeSet). En estos casos también es necesario al igual que antes analizar que :
a) Si tipo de dato a ordenar puede usar un mecanismo natural que de ordenación, no hace
falta nada para ordenar la colección, está ordenada automáticamente
b) Si el tipo de dato a ordenar es un objeto sin orden natural, se debe usar Comparator y
Comparable
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ La interfaz Comparable para que se use correctamente obliga a tres pasos:
Implementar Comparable indicando el tipo de dato que se va a comparar:
Implementar el método compareTo(obj1) (obligatorio al implementar Comparable)
Ver en la página siguiente como escribir un método compareTo
Finalmente, cuando la clase ya implemente Comparable puede ordenarse directamente en:
❖ Listas y arrays mediante los métodos Collections.sort() y Arrays.sort(). (Ejemplo alfa siguiente)
❖ También pueden ordenarse las claves en un mapa ordenado TreeMap (Ejemplo beta siguiente)
❖ Como elementos de un set ordenado TreeSet (sin necesidad de métodos). (Ejemplo delta siguiente)
Comparable
Interfaz Comparable
26
class Persona implements Comparable<Persona> {
Comparable es una interfaz genérica, hay
que poner la clase que se va a comparar
Comparable y Comparator
๏ Comparable y Comparator se usan para ordenar colecciones de objetos que no tienen orden natural
๏ La diferencia entre una y otra es que con Comparable sólo se puede usar un criterio de ordenación en la colección,
mientras que con Comparator se puede ordenar la colección, si es necesario, de diversas formas
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ El método recibe como parámetro un objeto con el que comparar , de forma que la comparación se realizará del
objeto en si (this) con el objeto pasado como parámetro.
compareTo( obj1 )
๏ El método debe devolver un valor entero que será según los casos;
‣ un número negativo si el objeto-base (this) es menor que el parámetro
‣ un cero si es igual que el parámetro
‣ un número positivo si el objeto-base es mayor que el parámetro.
๏ Por lo general, se usan uno o varios atributos de la clase para efectuar la comparación entre objetos y por lo tanto la
ordenación. Aquí podemos tener varios casos, según el tipo de dato a comparar :
Comparable: compareTo 27
class Persona implements Comparable<Persona> {
String nombre;
public Persona (String n) {
this.nombre = n;
}
@Override // metodo compareTo con objetos
public int compareTo (Persona p) {
return nombre.compareTo (p.nombre);
}
}
a) Que el atributo sea un objeto, como String o Date.
Para obtener el valor de retorno, usamos el propio
método compareTo del objeto
b) Que el atributo sea un tipo primitivo numérico. Se
puede hacer restando los valores a comparar
(primero el propio y luego el del parámetro):
En la clase Persona, si se ordena por el nombre que es String, se usa
compareTo de los nombres para que nos den directamente el valor a devolver:
También se puede hacer varios if que devuelven -1, 0 o 1 segun lo que se
desee
class Persona implements Comparable<Persona> {
int edad;
public Persona (int s) {
this.edad = e;
}
@Override // metodo compareTo con primit.
public int compareTo (Persona p) {
return this.edad - p.edad;
}
}
método compareTo()
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Ejemplos de comparable
Ejemplos de usos de Comparable
28
public static void main (String[] args) {
Set<Persona> p = new TreeSet<Persona> ();
p.add (new Persona ("Luis", "Ruiz"));
p.add (new Persona ("Pablo", "Martinez"));
p.add (new Persona ("Alberto", "Lopez"));
p.add (new Persona ("Cesar", "Perez"));
for (Persona persona : p)
System.out.println (persona);
}
public static void main (String[] args) {
Map<String, Persona> p = new TreeMap<> ();
p.put ("Ruiz", new Persona ("Luis", "Ruiz"));
p.put ("Martinez",new Persona ("Pablo", "Martinez"));
p.put ( "Lopez",new Persona ("Alberto", "Lopez"));
p.put ("Perez", new Persona ("Cesar", "Perez"));
for (String ape : p.keySet ())
System.out.println (ape);
}
public static void main (String[] args) {
List<Persona> p = new ArrayList<Persona> ();
p.add (new Persona ("Luis", "Ruiz"));
p.add (new Persona ("Pablo", "Martinex"));
p.add (new Persona ("Alberto", "Lopez"));
p.add (new Persona ("Cesar", "Perez"));
Collections.sort (p);
for (Persona persona : p)
System.out.println (persona);
}
class Persona implements Comparable<Persona> {
private String nombre;
private String apellido;
public Persona (String nombre, String apellido) {
this.nombre = nombre;
this.apellido = apellido;
}
@Override
public int compareTo (Persona p) {
return nombre.compareTo (p.nombre);
}
public String toString(){
return nombre+" "+apellido;
}
}
consola
Alberto Lopez
Cesar Perez
Luis Ruiz
Pablo Martinez
Comparable con ArrayList y Collections.sort()
consola
Lopez
Martinez
Perez
Ruiz
Comparable con TreeMap y sin mas metodos. Solo quedan ordenadas las claves,
pues no pueden quedar ordenados los valores, y que las claves se autoordenan
por que son una Set en si mismas, y de un tipo de orden natural
Comparable con TreeSet, sin necesidad de usar métodos
consola
Alberto Lopez
Cesar Perez
Luis Ruiz
Pablo Martinez
★ Hay que tener en cuenta que cuando las comparaciones son con
objetos, si se comparan objetos de clases diferentes, puede
lanzar un ClassCastException.
★ Se puede implementar la interfaz sin tipo genérico, definiendo
solamente implements Comparable. En este caso, será Object el
parámetro del método compareTo (compareTo (Object ob) ) y
dentro del método hay que tener cuidado de hacer los cast
necesarios !!
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Comparable sólo puedo establecer un método de ordenación, pues solo puedo escribir un método compareTo,
ya que este no es sobrecargable (p.e. la clase Persona del ejemplo anterior, si se ordena por nombre, luego no
se puedo intentar ordenar por edad)
๏ Comparator si permite varias ordenaciones, y su uso es muy parecido al de Comparable. Pasos para usarla:
No se va a tener que cambiar nada en la clase que vamos luego a comparar (Personaje), a diferencia
de Comparable
Se ha de crear una clase nueva, propia, que debe implementar Comparator, indicando el tipo de dato
que se va a comparar:
En esta clase nueva creada, hay que implementar el método compare(obj1, obj2) (nos obliga
Comparator a implementarlo).
Ver en la página siguiente como escribir la clase con su método compare()
Esta clase nueva creada, que implementa Comparator, podemos usarla para ordenar de estos
modos:
❖ Listas y arrays mediante los métodos Collections.sort() y Arrays.sort(), añadiendo un segundo
parametro, ademas de la colección a ordenar, un objeto de la clase-comparator (Ejemplo alfa)
❖ También pueden ordenarse las claves en un mapa ordenado TreeMap (Ejemplo beta)
❖ Como elementos en un set ordenado TreeSet, para lo cual debemos crear un un objeto de la clase-
comparator que se le pasa como parámetro al constructor de la colección, a la hora de crearla
(Ejemplo gamma)
Comparator
Interfaz Comparator
29
class MiClaseParaOrdenarPorNombre implements Comparator<Persona> {...}
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Nos obliga Comparator a implementarlo dentro de la clase que creemos. Es muy parecido al compareTo() que
vimos en Comparable:
๏ El método recibe esta vez como parámetros dos objetos con los que hacer la comparación:
compare(obj1, obj2)
๏ El método debe devolver un valor entero con la misma casuística que se usa en Comparable;
‣ un número negativo si el parámetro1 es menor que el parámetro2,
‣ un cero si son iguales ambos parámetros
‣ y un número positivo si el parámetro1 es mayor que el parámetro2,.
๏ Por lo general, también como en Comparable se usan uno o varios atributos de la clase para efectuar la
comparación, y nuevamente habrá dos casos, según el tipo de dato que usemos para ordenar:
Comparator: compare() 30
método compare()
class ModeloComparador implements Comparator<Humano>
{
@Override
public int compare (Humano p1, Humano p2) {
return (p1.nombre.compareTo (p2.nombre));
}
}
class ModeloComparador2 implements Comparator<Humano>
{
@Override
public int compare (Humano p1, Humano p2) {
return (p1.edad - p2.edad);
}
}
a) Que el atributo sea un objeto, como String o Date.
Para obtener el valor de retorno, usamos el propio
método compareTo del objeto
b) Que el atributo sea un tipo primitivo numérico. Se
puede hacer restando los valores a comparar (de
ambos parámetros):
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Comparator: ejemplos
Ejemplos de usos de Comparator
31
public static void main (String[] args) {
ModeloComparador modcom3 = new ModeloComparador ();
Set<Humano> ppp = new TreeSet<> (modcom3);
ppp.add (new Humano ("Luis", 23));
ppp.add (new Humano ("Pablo", 22));
ppp.add (new Humano ("Alberto", 18));
ppp.add (new Humano ("Cesar", 34));
for (Humano serhumano : ppp)
System.out.println (serhumano.nombre);
}
public static void main (String[] args) {
List<Humano> p = new ArrayList<Humano> ();
p.add (new Humano ("Luis", 23));
p.add (new Humano ("Pablo", 22));
p.add (new Humano ("Alberto", 18));
p.add (new Humano ("Cesar", 34));
ModeloComparador modcom = new ModeloComparador ();
Collections.sort (p, modcom);
for (Humano serhumano : p)
System.out.println (serhumano.nombre);
}
class Humano {
public String nombre;
public int edad;
public Humano (String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public String toString () {
return (nombre + " " + edad);
}
}
public static void main (String[] args) {
// Map<Humano, String> ppp = new TreeMap<> (); // ESTO DA ERROR
// pues intenta autoordenar la clave, que no es de orden natural
ModeloComparador modcom2 = new ModeloComparador ();
Map<Humano, String> pp = new TreeMap<> (modcom2);
pp.put (new Humano ("Luis", 23), "Ruiz");
pp.put (new Humano ("Pablo", 22), "Martinez");
pp.put (new Humano ("Alberto", 18), "Lopez");
pp.put (new Humano ("Cesar", 34), "Perez");
for (Humano h : pp.keySet ())
System.out.println (h.edad);
}
Ejemplo alfa: Comparator con ArrayList y Collections.sort()
pero añadiendo la clase-comparator en el sort()
Ejemplo gamma: Comparator con TreeSetsin necesidad
de usar métodos, pero añadiendo la clase-comparator en
el constructor de la colección
Ejemplo beta: Comparator con TreeMap y sin más metodos, pero
añadiendo la clase-comparator en el constructor de la colección
Advertir que lo que queda ordenado son las claves, pues no pueden quedar
ordenados los valores, y que las claves NO se autoordenan por que son
una Set en si mismas, pero NO de un tipo de orden natural
consola
Alberto Lopez
Cesar Perez
Luis Ruiz
Pablo Martinez
consola
18
22
23
34
consola
Alberto
Cesar
Luis
Pablo
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Resumen ordenación: Arrays
Resumen: si se necesita ordenar Arrays
Para ordenar arrays se puede usar Arrays.sort()
1. Si son datos con orden natural, ejecutando simplemente Arrays.sort( listaaordenar)
2. Si son datos objetos:
a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1), y ademas
ejecutar Arrays.sort(listaaordenar)
b) Usar un objeto de una clase que implemente la interfaz Comparator en el método
Arrays.sort(arrayaordenar,objetoComparator)
3. Para ordenar descendentemente, usar Arrays.sort(arrayaordenar, Collections.reverseOrder()) (No válido para primitivos)
32
System.out.println ("-- Ordenando ARRAYS con tipos primitivos");
String[] p = new String[3];
p[0] = "Luis";
p[1] = "Pablo";
p[2] = "Alberto";
// usando el metodo Arrays.sort(array)
// vale para cualquier tipo primitivo y String
Arrays.sort (p);
for (String mm : p) {
System.out.println (mm);
}
System.out.println ("----------");
char[] h = new char[3];
h[0] = 'w';
h[1] = 'a';
h[2] = 't';
Arrays.sort (h);
for (int mm : h) {
System.out.println ((char) mm);
}
System.out.println ("—- Ordenando ARRAYS con objetos");
Humano[] listaper = new Humano[3];
listaper[0] = new Humano ("Juan", 32);
listaper[1] = new Humano ("Ana", 21);
listaper[2] = new Humano ("Marta", 46);
Arrays.sort (listaper); // Arrays.sort(array) vale para objetos,
for (Humano mm : listaper) { // sólo si tienen compareTo en la clase
System.out.println (mm.nombre); // que se ordena y se implementa Comparable
}
//Clase Humano
class Humano implements Comparable<Humano> {
String nombre;
int edad;
public Humano (String n, int e) {
this.nombre = n;
this.edad = e;
}
@Override
// metodo compareTo sencillo
public int compareTo (Humano p) {
return nombre.compareTo (p.nombre);
}
}
consola
-- Ordenando ARRAYS con tipos primitivos
Alberto
Luis
Pablo
----------
a
t
w
----------
Ana
Juan
Marta
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Resumen: si se necesita ordenar Listas
Para ordenar Listas, da igual ArrayList o LinkedList o Vector , se usa Collections.sort()
1. Si son datos con orden natural, ejecutando simplemente Collections.sort( listaaordenar)
2. Si son datos objetos:
a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1), y ademas
ejecutar Collections.sort(listaaordenar)
b) Usar un objeto de una clase que implemente la interfaz Comparator en el método
Collections.sort(arrayaordenar,objetoComparator)
33
System.out.println ("-- Ordenando un ArrayList de tipos primitivos");
// necesitamos de un Collections.sort()
List<String> p1 = new ArrayList<> ();
p1.add ("Luis");
p1.add ("Pablo");
p1.add ("Alberto");
Collections.sort (p1);
for (String nombre : p1)
System.out.println (nombre);
System.out.println ("-- Ordenando un ArrayList de objetos");
// necesitamos de un Collections.sort()
List<Humano> listaper2 = new ArrayList<> ();
listaper2.add (new Humano ("Juan", 32));
listaper2.add (new Humano ("Ana", 21));
listaper2.add (new Humano ("Marta", 46));
Collections.sort (listaper2);
for (Humano pp : listaper2)
System.out.println (pp.nombre);
//Clase Humano
class Humano implements Comparable<Humano> {
String nombre;
int edad;
public Humano (String n, int e) {
this.nombre = n;
this.edad = e;
}
@Override
// metodo compareTo sencillo
public int compareTo (Humano p) {
return nombre.compareTo (p.nombre);
}
}
consola
-- Ordenando ArrayList con tipos primitivos
Alberto
Luis
Pablo
----------
Ana
Juan
Marta
Resumen ordenación: Listas
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Resumen: si se necesita ordenar Maps
Para ordenar Maps, solo podremos ordenar las claves, nunca los valores
• Con HashMap no están ordenados ni las claves ni los valores
• Con TreeMap para ordenar las claves :
1. Si las claves son datos con orden natural, están ordenadas implícitamente
2. Si las claves son de objetos:
a) Usar la interfaz Comparable en la clase
que se ordena, sobrescribiendo
compareTo(obj1)
b) Usar un objeto de una clase que
implemente la interfaz Comparator en el
constructor del TreeMap:
34
ClaseComparador miclas = new ClaseComparador ();
Map<Humano, String> pp = new TreeMap<> (miclas);
consola
---- Ordenando un HashMap por valores
primitivos
Alberto
Pablo
Norberto
Luis
-- Ordenando un HashMap por claves
primitivas
2
3
4
-- Ordenando un TreeMap por valores
Pablo
Alberto
Luis
Clave : 2 Valor :Pablo
Clave : 3 Valor :Alberto
Clave : 4 Valor :Luis
System.out.println ("-- Ordenando un HashMap por valores primitivos");
// no se puede usar Collections.sort()
// con lo que un HashMap directamente NO puede ordenarse
Map<Integer, String> p5 = new HashMap<> ();
p5.put (44, "Luis");
p5.put (22, "Pablo");
p5.put (33, "Alberto");
p5.put (11, "Norberto");
for (String nombre : p5.values ())
System.out.println (nombre);
System.out.println ("-- Ordenando un HashMap por claves primitivas");
// no hace falta usar Collections.sort()
// ya que el conjunto de claves es un set autoordenado
Map<Integer, String> p2 = new HashMap<> ();
p2.put (4, "Luis");
p2.put (2, "Pablo");
p2.put (3, "Alberto");
for (int nombre : p2.keySet ())
System.out.println (nombre);
System.out.println ("-- Ordenando un TreeMap por valores ");
// no hace falta usar Collections.sort()
// ya que el TreeSet garantiza orden por claves (no por por valores)
Map<Integer, String> p27 = new TreeMap<> ();
p27.put (4, "Luis");
p27.put (2, "Pablo");
p27.put (3, "Alberto");
for (String nombre : p27.values ())
System.out.println (nombre);
Iterator iterator = p27.keySet().iterator();
while (iterator.hasNext()) {
Object key = iterator.next();
System.out.println("Clave : " + key + " Valor :" + p27.get(key));
}
Resumen ordenación: Maps
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Resumen: si se necesita ordenar Sets
Para ordenar Sets, depende de que clases usemos:
• Con HashSet no se puede ordenar sus valores
• Con TreeSet
1. Si son datos con orden natural, están ordenadas implícitamente
2. Si son datos de objetos:
a) Usar la interfaz Comparable en la clase
que se ordena, sobrescribiendo
compareTo(obj1)
b) Usar un objeto de una clase que
implemente la interfaz Comparator en el
constructor del TreeSet:
35
System.out.println ("-------------- con un HashSet");
// no se puede ordenar un hashSet()
Set<String> p3 = new HashSet<> ();
p3.add ("Luis");
p3.add ("Pablo");
p3.add ("Alberto");
for (String nombre : p3)
System.out.println (nombre);
System.out.println ("-------------- con un TreeSet");
// no hace falta usar Collections.sort()
// ya un treeset esta autoordenado
Set<String> p35 = new TreeSet<> ();
p35.add ("Luis");
p35.add ("Pablo");
p35.add ("Alberto");
for (String nombre : p35)
System.out.println (nombre);
consola
----------- con un HashSet
Alberto
Luis
Pablo
----------- con un TreeSet
Alberto
Luis
Pablo
ClaseComparador miclas = new ClaseComparador ();
Set<Humano> pp = new TreeSet<> (miclas);
Resumen ordenación: Sets
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Puntos resumen más importantes en temas de ordenación;
• Los valores de TreeSet están ordenados implícitamente, si son datos con orden natural
• Si hay que ordenar objetos sin orden natural, hemos de usar siempre “comparadores” (Comparator o Comparable)
• Los valores de arrays, List y Sets se puede ordenar mediante programación con métodos sort(), añadiendo
Comparable, o ambas cosas
• Los valores de los Map no se pueden ordenar, como mucho, las claves.
• Los valores de los HashXXX no se pueden ordenar. Solo se pueden ordenan las claves de un HashMap (y es por
que las claves son un Set en si mismas, si se extraen y ordenan por mecanismos de ordenación de un Set)
Cuadro comparativo colecciones
Resumen: Comparador de colecciones
ARRAYS LISTS MAPS SETS
array ArrayList HashMap TreeMap HashSet TreeSet
Descripcion
lista fija de cosas lista de cosas
grupo de cosas con
indice único
grupo de cosas con
indice único
grupo de cosas
únicas
grupo de cosas únicas
Redimensionable no si si si si si
Permite duplicados si si si si no no
acceso por indice si si no no no no
acceso por clave propia no no si si no no
Ordenación implícita
(sin necesidad de codificación
expresa)
no no no
SI, sólo las claves
y solo si son con orden
natural
no
SI,
solo si son con orden
natural
Ordenación programada
(añadiendo Comparable u otros
métodos)
Por “comparadores” se entiende uso
de Comparable o Comparator
SI,
con Arrays.Sort()
y además “comparadores”
para objetos
SI,
con Collections.Sort()
y además “comparadores”
para objetos
no
SI, sólo las claves
y además con
“comparadores” para
objetos
no
SI,
con “comparadores” para
objetos
36
๏ Esta tabla ofrece una comparación de las características de los principales tipos de colección.
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Elegir TreeSet, sin tener
que hacer nada más, los
elementos están ordenados
Cuadro de elección de colección a usar
Resumen: Elegir qué colección usar si hay que ordenarla
El contenido de la colección tiene
orden natural (no tiene como
contenido objetos de clases propias)
El contenido de la colección tiene
objetos de clases propias
Elegir un array y ordenarlo por
Arrays.sort(array), o elegir una List y
ordenar por Collections.sort(coleccion),
NO Tiene elementos
repetidos
En la clase que compone la colección,
implementar Comparable<MiClase> y
sobrescribir compareTo(MiClase c)
Se necesita ordenar la colección por más de
un criterio de ordenación
Se necesita un único criterio de ordenación
Elegir TreeSet, y en su constructor,
añadir como parámetro un objeto de
MiOrden:
Elegir un array y ordenarlo por
Arrays.sort(array, MiOrden), o elegir una List y
ordenar por Collections.sort(coleccion, MiOrden)
Tiene elementos
repetidos
NO Tiene elementos
repetidos
Tiene elementos
repetidos
class Figura implements Comparable<Figura> {
private String nombre ;
public int largo ;
public String getNombre() {
return nombre;
}
public int compareTo(Figura f) {
return nombre.compareTo (f.getNombre ());
}
}
Para cada criterio de ordenación, crear una clase
nueva (p.e. MiOrden) que implemente
Comparator<MiOrden> y sobrescribir
compare(MiOrden c, MiOrden d)
class MiOrden implements Comparator<Figura>{
public int compare (Figura a, Figura b) {
return a.getNombre().compareTo(b.getNombre ());
}
}
class MiOrden2 implements Comparator<Figura>{
public int compare (Figura a, Figura b) {
return a.largo - b.largo;
}
}
Set<Figura> a = new TreeSet<>(new MiOrden());
List<Figura> b = new ArrayList<>();
Collections.sort (b,new MiOrden());
Figura [] c = new Figura [5];
Arrays.sort (c , newMiOrden());
List<Figura> b = new ArrayList<>();
Collections.sort (b);
Figura [] c = new Figura [5];
Arrays.sort (c);
37
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
Cuidado con TreeSet com Comparator y Comparable
Aunque ya se ha dicho, es necesario ahondar en el uso de los TreeSet, pues suele ser pregunta trampa de muchos exámenes.
Un TreeSet tiene sus elementos ordenados, pero necesita poder ordenarlos! No es opcional, tiene que saber ordenarlos
Si son de tipo de dato con orden natural, como int, funciona sin mas, pero si añadimos objetos a un TreeSet, hay de decirle con
un Comparator o Comparable como debe ordenar los objetos !!
En estos ejemplos, el primero de la derecha funciona, pero el segundo falla.
El primero contiene String, el otro objetos de tipo Humano... y falla al no saber ordenarlo:
Si queremos que funcione, hemos de hacer que la clase Humano implemente Comparable, o crear una clase de ordenación con
Comparator y se añada a la construcción del TreeSet como parámetro del constructor.
Esta segunda es la solución que se incluye aqui abajo(se ha marcado en rosa la inclusión de un objeto de la “clase ordenadora” en
el constructor del TreeSet)
TreeSet con Comparator y Comparable 38
public class EjemploComparator {
public static void main (String[] args) {
Set<String> p1 = new TreeSet<> (); // OK, BIEN
p1.add ("Luis");
Set<Humano> p2 = new TreeSet<> ();
p2.add (new Humano ("Luis", 32 )); //ERROR
}
}
class Humano {
String nombre;
int edad;
public Humano (String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
}
class EjemploComparator {
public static void main (String[] args) {
Set<Humano> p = new TreeSet<> (new modeloComparador ());
p.add (new Humano ("Luis", 23));
p.add (new Humano ("Alberto", 18));
p.add (new Humano ("Cesar", 34));
for (Humano serhumano : p)
System.out.println (serhumano.nombre);
}
}
class modeloComparador implements Comparator<Humano> {
@Override
public int compare (Humano p1, Humano p2) {
return (p1.edad - p2.edad);
}
}
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones equals y hashCode (I)
equals() y hashCode()
๏ hashCode() y equals() son dos métodos directamente heredados de Object. Tienen muchas
particularidades que los hacen necesitar un apartado especial para ellos:
1. hashCode()
✴ es un método que devuelve un integer, que es un identificador único del objeto.
✴ La implementación por defecto de hashCode() simplemente convierte la dirección de memoria del
objeto en un numero int
2. equals()
✴ compara dos objetos para ver si son o no iguales.
✴ Si no se sobrescribe, para decidir si los dos objetos son iguales comprueba simplemente las referencias
de ambos objetos, esto es, los compara con == .
๏ Ambos se usan en la mayoría de las colecciones para ver si un elemento existe en dicha colección, y para
borrarlo, especialmente en las colecciones que son de tipo Hash (HashTable, HashMap or HashSet.)
Cuando se busca un elemento en una colección, se intenta primero analizar si son iguales mirando si devuelve lo mismo el método hashCode().
Como esto puede ocurrir con varios elementos (ver parte avanzada para mas detalle), además de eso, posteriormente se mira si da true el método
equals()
๏ Por eso, por que se ejecutan en “comanda”, tienen un “contrato particular” que obliga a que, si se decide
sobrescribir equals() o hashCode() , deben entonces sobrescribirse AMBOS
๏ Pero en realidad, si ya existen, heredados, ¿por que habría necesidad de sobrescribirlos? Por que la igualdad de los objetos con equals() (mirar
solo su referencia) es muy pobre, y puede dar lugar a sorpresas si el uso no esta muy controlado (ver apéndice avanzado más adelante)
39
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Sobrescribir equals()
Cómo sobrescribir equals()
๏ Como ya se ha dicho, la implementación por defecto de equals() simplemente compara las direcciones de memoria de
los objetos, sus referencias.
๏ Esto quiere decir que deberemos sobrescribir equals() para hacerlo a nuestro gusto siempre que:
‣ Sepamos que vamos a realizar comparaciones con objetos de nuestra clase, y por lo tanto, lo mas lógico será usar
el propio método equals() para ello
‣ Sepamos que se van a crear colecciones con objetos de mi clase, y estas colecciones pueden ser de tipo Hash
40
// El método es public y recibe como parámetro un tipo Object, si no, no estaria
// sobrescribiendo equals()
public boolean equals (Object obj) {
// Comprueba si la referencia del objeto obj y el objeto que llama a equals
// son las mismas, en cuyo caso, son iguales los objetos, y devuelve true
if (this == obj) return true;
// Comprueba si la referencia del objeto parametro es null
// en cuyo caso, devuelve false directamente
if (obj == null) return false;
// Comprueba si la clase a la que pertenece el objeto parametro y
// el objeto que llama a equals son distintas, y devuelve false en tal caso
if (getClass () != obj.getClass ()) return false;
// Crea un objeto de tipo MiClaseCoche con un casting al
// parámetro recibido, para poder usarlo ahora despues
MiClaseCoche other = (MiClaseCoche) obj;
// Comparamos los atributos que queramos de los dos objetos
// para dar true o false a la comparacion
if (!marca.equals (other.marca)) return false;
if (matricula == null) {
if (other.matricula != null) return false;
}
else if (!matricula.equals (other.matricula)) return false;
return true;
}
Los IDE pueden
crear automáticamente
el metodo, y en el código
que crean puede haber
pistas de una buena
operativa a seguir con
este tipo de análisis
para comparar objetos.
Aunque si no se quiere
ser tan exigente, se
pueden hacer menos
análisis, eliminando
algunos de los que se
muestran en el ejemplo:
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Sobrescribir equals()
๏ El mecanismo normal para hacer un equals() en nuestra clase es comparar algunos de sus atributos.
๏ La comparación debe ser a gusto del usuario, buscando alguna regla que de true o false según las
necesidades. En este ejemplo, dos coches no serán iguales comparando sus matriculas, sino que se
considerará que son iguales si tienen la misma marca y modelo. Este es el equals() “reducido:
41
@Override
public boolean equals (Object obj) {
if (! ( obj instanceof MiClaseCoche)) return false;
// Crea un objeto de tipo MiClaseCoche con un casting al
// parámetro recibido, para poder usarlo ahora despues
MiClaseCoche otro = (MiClaseCoche) obj;
// Comparamos los atributos que queremos
if ((marca.equals (otro.marca)) && (modelo.equals (otro.modelo)) {
return true;
}
else {
return false;
}
}
Mucho cuidado a la hora de sobrescribir equals:
• boolean equals(Objeto o) {...} Esto NO sobrescribe equals(), el método debe ser declarado como public.
• public boolean equals(Demo o) {...}. Esto NO sobrescribe equals(), el método necesita un parámetro Object
• Reflexivo: Para un valor dado de un objeto x, x.equals(x) debe dar true.
• Simetrico: Dados unos objetos x y z, x.equals(z) debe dar true estrictamente sí (sí y solo sí) z.equals(x) es true.
• Transitivo. Dados unos objetos w, x y z, si w.equals(x) da true y x.equals(z) da true, entonces w.equals(z) debe dar true.
• Consistente: Dados unos objetos x y z, varias llamadas a x.equals(z) deben dar consistentemente true o false, si es que los valores utilizados
para la comparación de los objetos non ha sido modificados.
• Para cualquier caso en que x no sea null, x.equals(null) debe dar false.
Reglas que ha de seguir el método equals()Temas avanzados
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Sobrescribir hashCode()
๏ La implementacion por defecto de hashCode() (la que se hereda de Object) simplemente convierte la
dirección de memoria del objeto en un numero int
๏ Si sobrescribimos hashCode, para que tenga mas funcionalidad, debemos intentar que el método devuelva
enteros diferentes para objetos diferentes
๏ No es correcto usar funciones random para calcular un hashCode(), pues pueden no devolver el mismo
resultado a iguales llamadas en una misma ejecucion del programa.
๏ Normalmente se sobrescribe hashCode() usando el hashCode() de alguno o varios atributos
๏ Algunos ejemplos;
Cómo sobrescribir hashcode()
42
@Override
public int hashCode () {
final int prime = 31;
int result = 1;
result = prime * result + edad;
return result;
}
@Override
public int hashCode () {
return this.nombre.hashCode();
}
@Override
public int hashCode () {
return this.nombre.hashCode() + this.edad;
}
• Si objeto1 y objeto2 son iguales, según el método equals(), han de serlo siempre también con el método hashcode()
• Si objeto1 y objeto2 son iguales, según el método hashchde(), no tienen por que ser iguales con el método equals()
Reglas que ha de seguir el método hashcode()Temas avanzados
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Cuando se vieron los principales principios de POO, se dejó para este momento la explicación del principio
de desacoplamiento.
๏ Este principio facilita el que cuando se programa un método o una clase, no tiene ésta que depender de un
tipo específico de datos, sino que use conceptos como Interfaz para que sea el valor que devuelva un
método, y aprovechándose del polimorfismo, permitir que en el futuro pueda tener independencia a
la hora de cambiar mis programas.
๏ Por ejemplo, List es una interfaz (implementada en todas las colecciones de listas, entre otras por
Arraylist). En este ejemplo de método, deseo devolver una lista. Si lo construyo así:
En este caso, no devuelvo un Arraylist, sino un List. Cualquiera que llame a este método obtiene un List,
que lo puede convertir a Arraylist o a LinkedList a lo que quiera.
Y además, aun más importante, si en el futuro necesito cambiar mi método y dentro de él no trabajar con
Arraylist, puedo hacer los cambios que sean por otra clase, y la capa que llame a mi método no se ve
afectada (siempre que la nueva clase implemente también List, claro)
Desacoplamiento
Desacoplamiento
43
public List<persona> obtener () {
ArrayList<Persona> aa …
….
return aa
}
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
๏ Usar el método estático asList() de la clase Arrays, que devuelve un objeto de tipo List
Formato: lista objetolista = Arrays.asList( unarray );
๏ Cuidado : ambos objetos quedan “enlazados” por una referencia al mismo conjunto de objetos, lo que significa
que los cambios que se realicen en la colección se efectúan automáticamente en el array, y viceversa.
๏ Usar el método estático toArray() de la interfaz List, que devuelve un array de Object
Formato: tipodedatodelarray unarray = Collections.toArray( unacoleccion)
๏ Cuidado : el array es una copia del conjunto de datos de la colección, por lo que los cambios que se realicen
en la colección NO afectan al array, ni viceversa.
Conversiones Colecciones - Arrays
Convertir un array en una colección
Convertir una colección en un array
44
ArrayList<String> ciudades = new ArrayList<>();
ciudades.add("Madrid");
ciudades.add("León");
ciudades.add("Granada");
Object [ ] arrayciu = ciudades.toArray();
String [ ] ciudades = {"Madrid","Leon","Granada"};
List<String> listaciu = Arrays.asList(ciudades);
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones Avanzado 45
- Una colección tipo hash guarda sus elementos en una estructura indexada.
- Para saber que índice tiene cada elemento (al insertarlo o consultado o borrarlo) se aplica al mismo una función hash que
indica donde se encuentra o se va a colocar el elemento (en Java la función hash que se aplica es el resultado de hashcode())
- Una colección hash es muy eficiente en las búsquedas, pues puede hacerlas binarias.
- Sin embargo, una función hash no puede asegurar que no de el mismo resultado para dos elementos. Esto provoca
“colisiones”
- Paso a paso, cuando se busca un elemento en una tabla hash, por lo tanto, se efectúa este proceso:
a) se calcula su posición con la función hash, lo que determina un cierto “area” donde debe estar (en java se
calcula este “área” con el método hashcode()
b) Se busca el elemento en dicha área
c) Se mira si hay mas elementos en esa área (que deben entonces tener la misma clave hash)
d) Si existen varios, se promueve algún mecanismo de solución de la “colisión”
e) El mecanismo que usa Java es aplicar ahora equals() entre los objetos del área para determinar cuál es el
deseado.
Así vemos el uso combinado de hashcode() y equals() en colecciones tipo hash
Importantes a tener en cuenta con hashcode() y equals();
- Dos objetos iguales deben producir el mismo resultado al aplicar equals(). Sin embargo, objetos diferentes pueden producir
equals() iguales
- El método equals() provee comparación “profunda” al comparar dos objetos, mientras que el operador == provee una
comparación "shallow" (superficial) (Ver capitulo de objetos, apartado de Temas Avanzados)
Colecciones Hash mas en detalleTemas avanzados
TemariodecursoJavaSE©IñakiMartín
11.- Colecciones
• Analicemos despacio los “sysout” de este ejemplo:
• ¿Qué ha pasado? Pues que no se han encontrado los elementos en la colección. Si se hubiera usado
sí se habría encontrado el elemento, pero usando
no se encuentra, pues equals() no da true, al no ser los mismos objetos, al tener distinta referencia
• Por eso es conveniente, si se va a trabajar con colecciones, sobrescribir los métodos equals() y
hashCode() de todas las clases que intervengan como valor de ordenación.
Cuando faltan equals() y hashcode() ....Temas avanzados
equals y hashCode (II)
/* — Ejemplo de ejecución del programa:
Tamaño del conjunto: 5
miConjunto.contains( new Actor(25)): false
miConjunto.remove( new Actor(24): false
Tamaño otra vez del conjunto: 5
*/
46
System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (new Actor (24)));
System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (act2));
Actor act1 = new Actor (23);
Actor act2 = new Actor (24);
Actor act3 = new Actor (25);
Actor act4 = new Actor (26);
Actor act5 = new Actor (27);
Set<Actor> miConjunto = new HashSet<Actor> ();
miConjunto.add (act1);
miConjunto.add (act2);
miConjunto.add (act3);
miConjunto.add (act4);
miConjunto.add (act5);
System.out.println ("Tamaño del conjunto: " + miConjunto.size ());
System.out.println ("miConjunto.contains( new Actor(25)): " + miConjunto.contains (new Actor (25)));
System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (new Actor (24)));
System.out.println ("Tamaño otra vez del conjunto: " + miConjunto.size ());

Más contenido relacionado

La actualidad más candente

Tema 6 colecciones por gio
Tema 6   colecciones por gioTema 6   colecciones por gio
Tema 6 colecciones por gioRobert Wolf
 
Colecciones en Java
Colecciones en JavaColecciones en Java
Colecciones en JavaRonny Parra
 
Programación 3: Vector, stack, enumearator, iterator, listiterator en Java
Programación 3: Vector, stack, enumearator, iterator, listiterator en JavaProgramación 3: Vector, stack, enumearator, iterator, listiterator en Java
Programación 3: Vector, stack, enumearator, iterator, listiterator en JavaAngel Vázquez Patiño
 
Clase6 collections
Clase6 collectionsClase6 collections
Clase6 collectionsjorg_marq
 
Iteradores, Listas y Conjuntos en Java
Iteradores, Listas y Conjuntos en JavaIteradores, Listas y Conjuntos en Java
Iteradores, Listas y Conjuntos en JavaGaby Delgado
 
DAW - Estructuras de almacenamiento
DAW - Estructuras de almacenamientoDAW - Estructuras de almacenamiento
DAW - Estructuras de almacenamientovay82
 
Java script estructuras_datos
Java script estructuras_datosJava script estructuras_datos
Java script estructuras_datosjcremiro
 
Tema 4 clases_y_objetos
Tema 4 clases_y_objetosTema 4 clases_y_objetos
Tema 4 clases_y_objetosBelenMonse
 
Elementos de una clase
Elementos de una claseElementos de una clase
Elementos de una claseIsaias Toledo
 
Algoritmo de listas simples completo
Algoritmo de listas simples  completoAlgoritmo de listas simples  completo
Algoritmo de listas simples completoBoris Salleg
 
Estructuradatospilasycolas 121106170754-phpapp02
Estructuradatospilasycolas 121106170754-phpapp02Estructuradatospilasycolas 121106170754-phpapp02
Estructuradatospilasycolas 121106170754-phpapp02Z Karina Hernandez A
 

La actualidad más candente (19)

Tema 6 colecciones por gio
Tema 6   colecciones por gioTema 6   colecciones por gio
Tema 6 colecciones por gio
 
Colecciones en Java
Colecciones en JavaColecciones en Java
Colecciones en Java
 
Array listlistas
Array listlistasArray listlistas
Array listlistas
 
Programación 3: Vector, stack, enumearator, iterator, listiterator en Java
Programación 3: Vector, stack, enumearator, iterator, listiterator en JavaProgramación 3: Vector, stack, enumearator, iterator, listiterator en Java
Programación 3: Vector, stack, enumearator, iterator, listiterator en Java
 
Clase6 collections
Clase6 collectionsClase6 collections
Clase6 collections
 
Iteradores, Listas y Conjuntos en Java
Iteradores, Listas y Conjuntos en JavaIteradores, Listas y Conjuntos en Java
Iteradores, Listas y Conjuntos en Java
 
DAW - Estructuras de almacenamiento
DAW - Estructuras de almacenamientoDAW - Estructuras de almacenamiento
DAW - Estructuras de almacenamiento
 
Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02
 
53 Php. Clases Y Objetos
53 Php. Clases Y Objetos53 Php. Clases Y Objetos
53 Php. Clases Y Objetos
 
Java script estructuras_datos
Java script estructuras_datosJava script estructuras_datos
Java script estructuras_datos
 
P2C5 Introducción a JEE5 - II
P2C5 Introducción a JEE5 - IIP2C5 Introducción a JEE5 - II
P2C5 Introducción a JEE5 - II
 
Tema 4 clases_y_objetos
Tema 4 clases_y_objetosTema 4 clases_y_objetos
Tema 4 clases_y_objetos
 
Elementos de una clase
Elementos de una claseElementos de una clase
Elementos de una clase
 
Guia poo
Guia pooGuia poo
Guia poo
 
HashTable
HashTableHashTable
HashTable
 
Matrices en php
Matrices en phpMatrices en php
Matrices en php
 
Arrays
ArraysArrays
Arrays
 
Algoritmo de listas simples completo
Algoritmo de listas simples  completoAlgoritmo de listas simples  completo
Algoritmo de listas simples completo
 
Estructuradatospilasycolas 121106170754-phpapp02
Estructuradatospilasycolas 121106170754-phpapp02Estructuradatospilasycolas 121106170754-phpapp02
Estructuradatospilasycolas 121106170754-phpapp02
 

Similar a Java Colecciones Listas

Declaración y creación de un arraylist
Declaración y creación de un arraylistDeclaración y creación de un arraylist
Declaración y creación de un arraylistRobert Wolf
 
Scala collections
Scala collectionsScala collections
Scala collectionscrissbal94
 
Vectores, array y sus métodos
Vectores, array y sus métodosVectores, array y sus métodos
Vectores, array y sus métodosOrlando Verdugo
 
Programación 3: listas y conjuntos en java
Programación 3: listas y conjuntos en javaProgramación 3: listas y conjuntos en java
Programación 3: listas y conjuntos en javaAngel Vázquez Patiño
 
[ES] Colecciones y estructura de iteracion
[ES] Colecciones y estructura de iteracion[ES] Colecciones y estructura de iteracion
[ES] Colecciones y estructura de iteracionEudris Cabrera
 
Algoritmos y Estructura de datos_Semana5 (3).ppt
Algoritmos y Estructura de datos_Semana5 (3).pptAlgoritmos y Estructura de datos_Semana5 (3).ppt
Algoritmos y Estructura de datos_Semana5 (3).pptDaveRodriguez22
 
javadesdecerocolecciones-140914051359-phpapp01.pptx
javadesdecerocolecciones-140914051359-phpapp01.pptxjavadesdecerocolecciones-140914051359-phpapp01.pptx
javadesdecerocolecciones-140914051359-phpapp01.pptxCompusoftnetCiaLtda
 
Mapas y Diccionarios - Colecciones Parametrizadas
Mapas y Diccionarios - Colecciones ParametrizadasMapas y Diccionarios - Colecciones Parametrizadas
Mapas y Diccionarios - Colecciones ParametrizadasChristian Collaguazo Malla
 

Similar a Java Colecciones Listas (20)

Arraylist
ArraylistArraylist
Arraylist
 
Array List
Array ListArray List
Array List
 
Declaración y creación de un arraylist
Declaración y creación de un arraylistDeclaración y creación de un arraylist
Declaración y creación de un arraylist
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Tema6
Tema6Tema6
Tema6
 
Colecciones en Scala
Colecciones en ScalaColecciones en Scala
Colecciones en Scala
 
Vectores, array y sus métodos
Vectores, array y sus métodosVectores, array y sus métodos
Vectores, array y sus métodos
 
Programación 3: listas y conjuntos en java
Programación 3: listas y conjuntos en javaProgramación 3: listas y conjuntos en java
Programación 3: listas y conjuntos en java
 
[ES] Colecciones y estructura de iteracion
[ES] Colecciones y estructura de iteracion[ES] Colecciones y estructura de iteracion
[ES] Colecciones y estructura de iteracion
 
Algoritmos y Estructura de datos_Semana5 (3).ppt
Algoritmos y Estructura de datos_Semana5 (3).pptAlgoritmos y Estructura de datos_Semana5 (3).ppt
Algoritmos y Estructura de datos_Semana5 (3).ppt
 
javadesdecerocolecciones-140914051359-phpapp01.pptx
javadesdecerocolecciones-140914051359-phpapp01.pptxjavadesdecerocolecciones-140914051359-phpapp01.pptx
javadesdecerocolecciones-140914051359-phpapp01.pptx
 
4_colecciones.ppt
4_colecciones.ppt4_colecciones.ppt
4_colecciones.ppt
 
Pilas y matrices (Stacks y Arrays) - Small Basic
Pilas y matrices (Stacks y Arrays) - Small BasicPilas y matrices (Stacks y Arrays) - Small Basic
Pilas y matrices (Stacks y Arrays) - Small Basic
 
Colecciones en Scala
Colecciones en ScalaColecciones en Scala
Colecciones en Scala
 
Vba y objetos excel
Vba y objetos excelVba y objetos excel
Vba y objetos excel
 
Listas, pilas y colas
Listas, pilas y colasListas, pilas y colas
Listas, pilas y colas
 
Java Collection Framework: lo que todo Java Dev debe conocer
Java Collection Framework: lo que todo Java Dev debe conocerJava Collection Framework: lo que todo Java Dev debe conocer
Java Collection Framework: lo que todo Java Dev debe conocer
 
A1 python 4
A1 python 4A1 python 4
A1 python 4
 
20152 sfiec030121 1
20152 sfiec030121 120152 sfiec030121 1
20152 sfiec030121 1
 
Mapas y Diccionarios - Colecciones Parametrizadas
Mapas y Diccionarios - Colecciones ParametrizadasMapas y Diccionarios - Colecciones Parametrizadas
Mapas y Diccionarios - Colecciones Parametrizadas
 

Más de Jyoc X

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc X
 
Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc X
 
Jyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc X
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc X
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc X
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc X
 
Jyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc X
 
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc X
 
Jyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc X
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc X
 
Jyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc X
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc X
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc X
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc X
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc X
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc X
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc X
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc X
 
Jyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc X
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc X
 

Más de Jyoc X (20)

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unit
 
Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridad
 
Jyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzado
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilas
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fx
 
Jyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nio
 
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
 
Jyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientes
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividad
 
Jyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc java-cap12 excepciones
Jyoc java-cap12 excepciones
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumerados
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios poo
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetos
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase string
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 bucles
 
Jyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcaciones
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salida
 

Último

Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...silviayucra2
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIAWilbisVega
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudianteAndreaHuertas24
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxJOSEMANUELHERNANDEZH11
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfsoporteupcology
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesFundación YOD YOD
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx241521559
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)GDGSucre
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 

Último (16)

Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptx
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdf
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento Protégeles
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 

Java Colecciones Listas

  • 1. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones 1 TEMARIO DE CURSO PROGRAMACIÓN JAVA SE CAPÍTULO 11 COLECCIONES © Iñaki Martín Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
  • 2. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ En Java, los array son de tamaño fijo, una vez declarados y asignado un tamaño, éste no puede cambiarse. ๏ Para trabajar con estructuras de datos dinámicas, esto es, cuyo tamaño pueda variar, se usan Colecciones. Colecciones : Conjunto de objetos, de tamaño dinámico. ๏ Para trabajar con colecciones, no se puede hacer con tipos primitivos (int, char, double…), solo con objetos. Por lo tanto, para trabajar con tipos parecidos a primitivos, podemos usar las clases envoltorios (por ejemplo, no se puede usar int ni double, pero sí Integer o Double ) Definir Colecciones Tipos de colecciones y definición 2 Desde Java 5 la conversión entre tipos primitivos y su clase envoltorio hace casting implícito, (autoboxing, para poder asignar directamente un int a un Integer, y viceversa con autounboxing), Con las clases envoltorio no es recomendable hacer operaciones matemáticas, pues hace una doble conversión interna que es poco productiva (sumar dos Integer supone convertir internamente ambos a int, operar, y convertir a Integer el resultado) Sin embargo, las clases envoltorio con claramente útiles cuando se trata de almacenamiento en colecciones ๏ Las clases de colección están en el paquete java.util, y son herencias todas de una interfaz madre ๏ Los tipos más importantes de colecciones son: ‣ Listas clases : ArrayList, Vector, LinkedList ( subclases de interfaz List ) ‣ Mapas clases : HashMap, TreeMap ( subclases de interfaz Map y Table ) ‣ Conjuntos clases : HashSet, TreeSet ( subclases de interfaz Set )
  • 3. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Diagrama de colecciones Diagrama de clases de colecciones ๏ Esta es una clasificación de las clases más importantes en relación a las colecciones Java ๏ Advertir que de la clase Collections solo heredan List y Set, no así en el caso de Map Leyenda 3
  • 4. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Resumen de colecciones Resumen tipos colecciones 4
  • 5. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Una lista es una colección que almacena los elementos junto con un identificador numérico asociado a cada uno ๏ Las características de una Lista son: ‣ El indicador (indice) es un entero creciente, muy parecido al de un array ‣ Es de tamaño variable, no fijo como un array ‣ Se puede acceder a los elementos (leer, añadir o borrar) por su posición a través del índice. ‣ Puede contener elementos duplicados ‣ List es la interfaz de la que cuelgan el resto de colecciones de lista; ArrayList, LinkedList, Vector, etc. ‣ Para construir una lista, se puede usar una clase "hija" de List aunque normalmente se suele usar con polimorfismo (ambas son perfectamente válidas): En este segundo caso, se aplica upcasting Colecciones de tipo Lista Listas 5 CLASELISTA<String> laLista2 = new CLASELISTA<String>(); List<String> laLista2 = new CLASELISTA<String>(); Sustituir CLASELISTA por una de las clases de tipo lista
  • 6. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Métodos básicos de tipo Lista 6 CLASE DEVUELVE METODO DESCRIPCION List boolean add (Object 0b) Mete un elemento al final de la lista List void add (int pos, Object elem) Mete un elemento en la posición indicada, moviendo el resto hacia adelante List Object get (int pos) Devuelve el elemento de la posición pos. Cuidado: devuelve Object si ArrayList si no tiene tipo. List object remove (int posicion) Elimina el elemento de la posición indicada. Devuelve dicho elemento. List int indexOf (Object ob) Devuelve el indice de la primera ocurrencia del objeto ob en la lista, o -1 si no lo encuentra List Object set (pos, elemento) Sustituye el elemento de la posición pos. Devuelve error si la posicion no existe List void clear() Elimina los elementos de la lista List boolean contains(Object ob) Informa de si un determinado contenido está en la colección. Cuidado: contains usa equals() para comparar, si se usan clases propias, es necesario sobreescribir equals() List int size () Devuelve el numero de elementos que tiene la objLista.add("Ejemplo"); // Suponiendo que la lista contenga Strings objLista.clear(); boolean existe = objLista.contains("Ejemplo"); // Suponiendo una lista de Strings int pos = objLista.indexOf("Ejemplo"); // Suponiendo que la lista contenga Strings objLista.remove(0); String res = objLista.get(0); objLista.add( 3, "Ejemplo"); // Suponiendo que la lista contenga Strings objLista.set( 1, "Otro Ejemplo"); // Suponiendo que la lista contenga Strings int tamano = objLista.size(); // Suponiendo una lista de Strings Métodos más importantes de LIST (Y de todas sus clases heredadas)
  • 7. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Otros métodos de tipo Lista 7 CLASE DEVUELVE METODO DESCRIPCION List boolean addAll(Collection cole) Mete todos los elementos de la coleccion cole al final de la lista. Añade los nuevos elementos, aunque ya estuvieran en la coleccion inicial, con lo que pueden aparecer repetidos List boolean remove (Object ob)) Elimina (la primera ocurrencia) del objeto parametro. Devuelve true si pudo eliminarlo List int lastIndexOf(Object obj) Devuelve el indice de la última ocurrencia del objeto parámetro dentro del objeto invocante. Devuelve -1 si no encuentra el objeto en la colección List List subList(int start, int end) Devuelve una lista sacando los elementos desde el indice start al índice end (“shallow” copy) List object toArray() Convierte un ArrayList en un array de Object, que necesitan casting posterior: Si no se desea usar el casting, hay otra forma de usar toArray() algo compleja: • El método toArray() debe recibir un parámetro que ha de ser un array para que lo llene, array del mismo tipo que la coleccion. • El array puede estar vacío, pero ha de estar creado y con tamaño suficiente. • Devuelve un array del mismo tipo que el la coleccion (que no es obligatorio usar) Si el array que se crea con toArray() no tiene el tamaño mínimo, se crea un nuevo array en tiempo de ejecución para almacenar el numero necesario de elementos. En este caso, el array que se modifica no es el que se pasa por parámetro, que queda a null, sino el que se devuelve por el método, igual que en el primer uso del método explicado mas arriba ArrayList<String> lista2 = new ArrayList<>(); lista2.add("Juan"); lista2.add("Pedro"); String [] nombres2 = (String []) objLista.toArray(); ArrayList<String> lista8 = new ArrayList<>(); lista2.add("Juan"); lista2.add("Pedro"); String[] nombres8 = new String[2]; nombres2 = objLista.toArray(nombres2); ArrayList<String> lista2 = new ArrayList<>(); lista2.add("Juan"); lista2.add("Pedro"); String[] nombres2 = new String[1]; String[] nombres3 = objLista.toArray(nombres2); Otros métodos menos importantes de LIST
  • 8. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Listas: ArrayList ๏ El objeto se crea: ๏ Desde JEE7 existe inferencia de tipos, que nos evita indicar nuevamente el tipo: ArrayList (hereda de List) 8 // ArrayList<tipo> variable = new ArrayList<tipo>(); ArrayList<String> laLista2 = new ArrayList<String>(); Un ArrayList es un tipo genérico, que se identifica por que al crear un objeto se debe indicar el tipo del dato que almacenará ArrayList<tipo> variable = new ArrayList<tipo>(); Si no se indica, se está creando igualmente un ArrayList, pero sin tipo asociado, esto es, se puede almacenar cualquier cosa dentro (de hecho, se almacenan objetos de tipo Object) ArrayList variable = new ArrayList(); A estos tipos construidos sin especificar genérico, se le denomina raw types. Los raw types, lejos de una ventaja, es un inconveniente pues nunca se sabe con certeza que tipo tiene cada elemento, con lo que - a la hora de extraer los elementos, hay que extraerlos como Object, y hacer un casting a lo que se quiera - Hay que adivinar hacia qué tipo de dato se desea hacer el casting.... Por lo tanto es mejor declarar siempre el tipo del dato de la colección, salvo que se desee explícitamente por alguna razón usar tipos raw Todo esto aplica a los ArrayList y a todas las Listas, Mapas o Conjuntos, explicados más adelante Consultar el capítulo que trata de Genéricos para ahondar en estos conceptos CLASE DEVUELVE METODO DESCRIPCION ArrayList Object clone () Devuelve una “shallow copy” (superficial) de la coleccion actual ArrayList void removeRange (int inicio, inf fin) Borra los elementos de la lista que se encuentren entre inicio (inclusive) y finn (exclusive) Métodos exclusivos de ArrayList (aunque los más importantes son los heredados de List) // ArrayList<tipo> variable = new ArrayList<>(); ArrayList<String> laLista2 = new ArrayList<>(); • La inferencia también aplica al resto de colecciones • Al <> se le llama, a veces, operador “diamante"
  • 9. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Muy parecida a ArrayList, con métodos casi iguales, pero tiene peor rendimiento que ArrayList. ๏ Es beneficioso su uso en proyectos multitarea, pues sus métodos están sincronizados. Esto perjudica el rendimiento, por lo que solo es interesante si se necesita utilizar multitarea. ๏ Además, permite definir un numero mínimo de elementos y gestionar el tamaño del almacenamiento Vector (hereda de List) ๏ Con metodos casi iguales que ArrayList, pero preparada para trabajar en modo pila o cola (con métodos para acceder y retirar elementos desde la cabeza o la cola de la coleccion) LinkedList (hereda de List) 9 CLASE DEVUELVE METODO DESCRIPCION LinkedList void addFirst (Object ob) Inserta el objeto ob al principio de la lista, desplazano los demas LinkedList void addLast (Object ob) Inserta el objeto ob al final de la lista LinkedList void descendingIterator () Devuelve un Iterator de los elementos en orden inverso LinkedList Object getFirst () Devuelve, sin eliminarlo, el primer elemento de la lista LinkedList Object getLast () Devuelve, sin eliminarlo, el ultimo elemento de la lista LinkedList Object peek () Devuelve, sin eliminarlo, el primer elemento de la lista LinkedList Object poll () Devuelve, y además elimina, el primer elemento de la lista LinkedList Object removeFirst () Devuelve, y además elimina, el primer elemento de la lista LinkedList Object removeLast () Devuelve, y además elimina, el ultimo elemento de la lista CLASE DEVUELVE METODO DESCRIPCION Vector boolean copyInto ( Object [] unarray) Copia los elementos del vector en el array Vector void ensureCapacity( int capacidad) Incrementa la capacidad del vector si es necesario, hasta asegurar que puede almacenar el numero minimo de elementos especificados por el atributo Capacidad Minima (se puede definr en el constructor) ๏ El objeto se crea: Vector<tipo> variable = new Vector<tipo>(); ๏ El objeto se crea: LinkedList<tipo> variable = new LinkedList<tipo>(); Métodos exclusivos de Vector (aunque los más importantes son los heredados de List) Métodos exclusivos de LinkedList (aunque los más importantes son los heredados de List) Listas: Vector y LinkedList
  • 10. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Recorriendo colecciones con For-each ๏ Desde java5 existe una variante de for(), llamada FOR EACH Usa una variable interna de control para recorrer una colección (array, List o cualquier otra) ๏ Su formato es el siguiente ; for (tipoDeCadaDatoDeLaColeccion unaVariable : coleccionARecorrer) { x = unaVariable; } ๏ Viene a hacer algo así como “Coge la colección puesta a la derecha de los dos puntos, y para cada vuelta del bucle, vas sacando un elemento y lo metes en la variable que se declara a la izquierda de los dos puntos” ๏ Así pues, unaVariable va pasando por cada uno de los elementos del array o de la colección que sea. ๏ Si la colección tiene un índice (como los arrays o los ArrayList) los elementos se van sacando en el orden del indice ๏ Solo se puede usar para lectura de los valores, ¡¡ no para asignación ni borrado de los mismos !! ๏ Tambien se puede usar for-each con un array For-Each (for avanzado) 10 for (int i=0; i< laLista.size (); i++) { System.out.println (laLista.get(i)); } for (Integer unnum : laLista) { System.out.println (unnum); } for (Persona per : laLista) { System.out.println (per.nombre); } ๏ Ejemplo de como se recorre una colección con un bucle for tradicional, y como se hacer con un for-each, tanto con tipos wrappers como con objetos (laLista representa la colección a recorrer)
  • 11. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ En estas clases los objetos no tienen un índice numérico, sino que tienen un índice popio, que se añade junto al propio dato a almacenar en la colección. ๏ Este índice se llama clave, y hace las funciones de índice, pero no ordenado. ๏ La información que se almacena se denomina valor ๏ Las características de un Mapa son: Colecciones de tipo MAPA o TABLA Mapas 11 ‣ La clave puede ser de cualquier tipo de objeto, no tipo primitivo (al igual que pasa con el valor) ‣ Es de tamaño variable, no fijo como un array ‣ Al crear el mapa, se debe indicar el tipo de la clave, y el tipo del valor almacenado en el mapa ‣ Se puede acceder a los elementos (leer, añadir o borrar) por su posición a través del índice. ‣ No puede contener elementos con la clave duplicada ‣ Map es la interfaz de la que cuelgan el resto de colecciones de mapas; HashMap, TreeMap, etc. ‣ Para construir una lista, se puede usar una clase "hija" de Map aunque normalmente se suele usar con polimorfismo (ambas son perfectamente válidas): CLASEMAPA<Integer, String> elMapa2 = new CLASEMAPA<>(); Map<Integer, String> elMapa2 = new CLASEMAPA<>(); Sustituir CLASEMAPA por una de las clases de tipo mapa
  • 12. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones CLASE DEVUELVE METODO DESCRIPCION Map int size () Devuelve el tamaño de la colección. Map object remove(ind) Elimina el elemento con el indice “ind”. Devuelve null si no existe el indice Map void clear() Elimina todos los elementos de la colección Map boolean containsKey (Object clave) Indica si existe esa clave en la colección Map boolean containsValue (Object valor) Indica si existe ese objeto-valor entre los valores de la colección Map object get (Object indice) Devuelve el valor asociado con el indice indicado por parámetro, o null si no existe el indice Map object put (Object clave, Object valor) Coloca una clave y valor en la coleccion. Si la clave ya existían se sobrescribe el antiguo valor. Devuelve el antiguo valor, si ya existía la clave, o null si no existía la clave Map Collection values() Devuelve una colección conteniendo únicamente los objeto-valor del mapa. Map Set keySet() Devuelve un conjunto (Set) conteniendo únicamente las objeto-clave del mapa. Map boolean isEmpty() Indica si la colección esta vacía Map Set entrySet() Devuelve un conjunto de elementos llamados Map.Entry, que son precisamente del mismo “tipo” que el mapa (esto es, el par de elementos clave-valor) (ver mas adelante ejemplos y detalle) 12 objMapa.size(); objMapa.remove( 32 ); // Suponiendo que el Mapa tenga Integer en la clave String elValor = objMapa.get(63); // Suponiendo que el mapa contenga Strings boolean existeLaClave = objMapa.containsKey(14); objMapa.clear(); objMapa.put( 19, "Juan"); // Suponiendo que el Mapa tenga Integer y String boolean existeElValor = objMapa.containsValue("Pepe"); ArrayList<String> v = objMapa.values(); TreeSet<Integer> v = objMapa.keys(); boolean estaVacioElMapa = objMapa.isEmpty(); Métodos más importantes de MAP (Y de todas sus clases heredadas) Métodos básicos de tipo MAP
  • 13. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones • Un objeto TreeMap se crea igual que cualquier otro mapa • Un TreeMap garantiza que los elementos del mismo están ordenados ascendentemente por la clave. La clave se ordena ascendentemente (si permite un orden natural de ordenación) o si se trata de una clase, según la implementación de Comparator que tenga (ver mas adelante) • Tiene muchos métodos además de los que sobrescrito de Map Mapas: TreeMap y HashMap TreeMap (de tipo Map) • Un objeto HashMap se crea igual que cualquier otro mapa • En el ejemplo, el Integer hace referencia al índice, mientras que el contenido de la tabla es un String • En un HashMap, no se puede garantizar el orden de los elementos, de hecho, puede variar durante la propia ejecución. • En un HashMap se permite que sea null tanto la clave como el valor. HashMap (de tipo Map) 13 CLASE DEVUELVE METODO DESCRIPCION HashMap Set clone() Devuelve una copia del map. Métodos exclusivos de HashMap (aunque los más importantes son los heredados de Map) CLASE DEVUELVE METODO DESCRIPCION TreeMap object ceilingEntry(clave ) Devuelve el valor asociado a la siguiente clave superior o igual en el orden a la pasada por parámetro, o null si no existe TreeMap object ceilingKey (clave) Devuelve la siguiente clave superior o igual en el orden a la pasada por parámetro, o null si no existe TreeMap object floorEntry(clave) Devuelve el valor asociado a la siguiente clave inferior o igual en el orden a la pasada por parámetro, o null si no existe TreeMap object floorKey(clave) Devuelve la siguiente clave inferior o igual en el orden a la pasada por parámetro, o null si no existe TreeMap Set entrySet() Devuelve como un conjunto (set) los valores de la colección. TreeMap object firstEntry() Devuelve, tomando los elementos ordenados, el valor del elemento de clave mas baja. TreeMap object firstKey() Devuelve, tomando los elementos ordenados, la clave mas baja (primera clave). TreeMap object lastEntry() Devuelve, tomando los elementos ordenados, el valor del elemento de clave mas alta TreeMap object lastKey() Devuelve, con los elementos ordenados, la clave mas alta (ultima clave). Métodos exclusivos de TreeMap (aunque los más importantes son los heredados de Map)
  • 14. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Al intentar usar un for-each con un mapa, se verá que no funciona recorriendo el mapa...¿por que? ๏ Un Mapa internamente guarda dos colecciones (los indices y los valores). Al recorrer con un for-each, hay que decirle a éste cuál de las dos colecciones ha de recorrer, si la de las claves o la de los valores ๏ Por lo tanto, no se puede recorrer directamente un mapa, hay que crear una colección intermedia de claves o de valores ๏ Esta coleccion intermedia ha de ser del tipo Collection, que es superclase de Listas y Conjuntos, con este uso: ✴ con el método .values() se consigue una colección con los valores del mapa. La coleccion es de la clase Collection Ya vimos que este método devuelve un objeto de tipo Collection con la colección de valores del mapa, que sí tiene un indice para poder usarse en un for-each ✴ con el método .keySet() se consigue una colección con los índices del mapa Ya vimos que este método devuelve un objeto de tipo Set (hija de Collection) con la colección de valores del mapa, que sí tiene un indice para poder usarse en un for-each ๏ Ejemplo: Partimos de este mapa ya creado: Recorriendo un Map ¿ Como recorrer un Map? 14 Map<Integer,String> miMapa = new HashMap<>(); miMapa.put(29,"Ana"); miMapa.put(17,"Mercedes"); miMapa.put(31,"Maria"); // Creando un objeto Collection y usándolo en for-each Collection<String> losvalores = miMapa.values(); for (String cadavalor : losvalores) { System.out.println(cadavalor); } // Usando en el for-each directamente el método values() for (String cadavalor : miMapa.values()) { System.out.println(cadavalor); } ✦ Recorriendo los valores: usando .values() // Creando un objeto Collection y usándolo en for-each Collection<Integer> lasclaves = miMapa.keySet(); for (Integer cadaclave : lasclaves) { System.out.println(cadaclave); } // Usando en el for-each directamente el método keySet() for (Integer cadaclave : miMapa.keySet()) { System.out.println(cadaclave); } ✦ Recorriendo las claves: usando .keySet() consola Ana Mercedes Maria consola 29 17 31
  • 15. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Ya se ha visto que de un mapa o se recorre la colección de valores o la de claves ๏ Pero, ¿y si quiero recorrer ambas colecciones a la vez? (conocer en un mismo bucle los valores y sus claves) ๏ Una solución es recorrer en un bucle las claves, y dentro del bucle, ir sacando los valores: ๏ Pero hay una solución que aporta java, más efectiva, usar el método entrySet() en el mapa. Así se usa: MapEntry 15 for (Integer cadaclave : miMapa.keySet()) { String cadavalor = miMapa.get(cadaclave); System.out.print(cadavalor); System.out.println(cadaclave); } - entrySet() en un mapa devuelve un conjunto de elementos llamados Map.Entry . - Cada Map.Entry es realmente un par de elementos (clave y valor), correspondiente a cualquier elemento del Mapa - De cada elemento del Map.Entry se puede extraer el valor con el método getValue() y la clave con el método getKey() ๏ Ejemplo: Analicemos como funciona Map.Entry, viendo los métodos necesarios al usarlo dentro de for-each; ‣ En la colección a recorrer, usar entrySet() en el mapa a recorrer ‣ En el elemento que entrega el for-each, poner como tipo Map.Entry<tipoClave, tipoValor> ‣ En el interior del for-each, usar con cada elemento getValue() (para valores) y getKey() (para claves): // En este caso es siempre mejor usar el método entrySet directamente dentro del for-each for (Map.Entry<Integer, String> cadaEntry : miMapa.entrySet() ) { System.out.println ("clave = " + cadaEntry.getKey() + ", valor = " + cadaEntry.getValue()); } MapEntry consola Ana29 Mercedes17 Maria31 consola Clave = 20, valor = Ana Clave = 10, valor = Mercedes Clave = 30, valor = Maria Map<Integer,String> miMapa = new HashMap<>(); miMapa.put(29,"Ana"); miMapa.put(17,"Mercedes"); miMapa.put(31,"Maria");
  • 16. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones • Los Set (conjuntos) son las colecciones más simples, pues agrupan objetos sin clave ni índice. • Sus principales características son: ✴ No existen métodos para recuperar un valor, pues no hay modo de identificarlos al no tener índice ni clave. ✴ Lo que sí que se puede es recorrer directamente con un for-each. ✴ No puede tener elementos duplicados, claro. ✴ Esta clase se usa por lo tanto solo para agrupar, y recorrer, pero no para recuperar nada específico ✴ Set es la interfaz de la que cuelgan el resto de colecciones de lista; HashSet, TreeSet, LinkedHashSet. Colecciones tipo SET (Conjunto) Set 16 CLASECONJUNTO<Integer, String> elMapa2 = new CLASECONJUNTO<>(); Set<Integer, String> elMapa2 = new CLASECONJUNTO<>(); Sustituir CLASECONJUNTO por una de las clases de tipo mapa
  • 17. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones 17 CLASE DEVUELVE METODO DESCRIPCION Set boolean add (Object obj) Añade un objeto a la colección. Si añadimos un elemento igual a uno existente, devuelve False y no hace nada. Si no existe, lo añade y devuelve True. Set int size () Devuelve el tamaño de la colección. Set object remove (Object obj) Elimina el elemento que contiene el valor indicado. Devuelve null si no existe el elemento Set boolean contains(Object obj) Informa de si un determinado contenido esta en la colección Set void clear() Elimina todos los elementos de la colección Set boolean isEmpty() Indica si la colección esta vacía Set Object [] toArray() Convierte un Set en un array de Object, que necesitan casting posterior. (Ver ejemplo en el caso de List) Set int addAll(Collection cole) Mete todos los elementos de la coleccion cole al final del conjunto Si hay elementos que ya existen en la coleccion origen, los sustituye Los elementos nuevos, los incorpora al conjunto objSet.add("Eva"); // Suponiendo que el Set contenga Strings objSet.size(); objSet.remove("Juan); // Suponiendo que el Set contenga Strings boolean existe = objSet.contains("Ana"); // Suponiendo un Set de Strings objMapa.clear(); boolean estaVacio = objSet.isEmpty("Ana"); // Suponiendo un Set de Strings Métodos más importantes de SET (Y de todas sus clases heredadas) Métodos básicos de tipo SET
  • 18. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones • Ordena los elementos en base al valor de su contenido (sea orden natural o por Comparator/ Comparable) • Ofrece peor rendimiento que otras clases • Un objeto TreeSet se crea igual que cualquier otro conjunto TreeSet (de tipo Set) • Ofrece el mejor rendimiento de todas las clases conjunto • No da ninguna garantía de como se ordenan los elementos ni en que orden se extraen • Permite elementos nulos • Un objeto TreeSet secrea igual que cualquier otro conjunto HashSet (de tipo Set) • Ofrece un rendimiento casi igual a HashSet • Ordena los elementos por el orden en que fueron añadidos a la coleccion LinkedHashSet (de tipo Set) 18 CLASE DEVUELVE METODO DESCRIPCION TreeSet Set clone() Devuelve una copia de la colección TreeSet object ceiling (Object obj) Devuelve el valor superior o igual en orden al dado por parámetro, o null si no existe TreeSet object floor (Object obj) Devuelve el valor inferior o igual en orden al dado por parámetro, o null si no existe TreeSet object first() Devuelve, tomando los elementos ordenados, el valor mas bajo (primer valor). TreeSet object last() Devuelve, tomando los elementos ordenados, el valor mas alto (ultimo valor). TreeSet Set headSet (Object obj) Devuelve en un conjunto (set) los valores de la colección menores o iguales al parámetro TreeSet Set tailSet (Object obj) Devuelve en un conjunto (set) los valores de la colección mayores o iguales al parámetro TreeSet Set subSet(int fromIndex, int toIndex) Devuelve el conjunto de elementos que se encuentran entre los índices indicados en los parámetros, desde el primer parámetro inclusive al segundo parámetro exclusive CLASE DEVUELVE METODO DESCRIPCION HashSet Set clone() Devuelve una copia de la colección Métodos exclusivos de TreeSet(aunque los más importantes son los heredados de Set) Métodos exclusivos de HashSet (aunque los más importantes son los heredados de Set) Set: TreeMap y HashMap
  • 19. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Clase Collections 19 ๏ Collections es la calse de la que heredan todos las clases de Listas y Conjuntos (los Mapas van por otras ramas) ๏ La clase ofrece muchos métodos que puede usar cualquier Lista o Conjunto ๏ Los métodos son todos static, con lo que se invocan con Collections directamente ๏ Si han de modificar una colección, la suelen recibir como argumento y la modifican directamente (no devuelven lo modificado) Métodos más importantes de COLLECTIONS (todos ellos STATIC) CLASE DEVUELVE METODOS (TODOS STATIC) DESCRIPCION Collections boolean addAll(Coleccion a, val1,val2,...) Añade a la coleccion indicada como priemr parámetro los elementos indicados como segundo y sucesivos parámetros Collections int binarySearch(Lista lis, objeto obj) Devuelve el índice del elemento obj, buscado dentro de la lista lis. Devuelve un número negativo si no encuentra el elemento. Solo vale para Listas. Realiza un búsqueda binaria. Collections int binarySearch(Lista lis, objeto obj, Comparator com) Devuelve el índice del elemento obj, buscado dentro de la lista lis. Devuelve un número negativo si no encuentra el elemento. Utililza el objeto Comparator comp para la búsqueda, que es búsqueda binaria. Collections void copy(Lista destino, lista origen) Copia los elementos de la lista origen en la lista destino. Solo vale con Listas. Duplica si hay repetidos Collections boolean disjoint(Coleccion c1, Coleccion c2) Devuevlve true si las colecciones espeficicadas no tienen elementos en comun Collections void fil(Lista lis1, objeto obj) Reemplaza en la lista lis1 todos los elementos con el elemento obj. Solo vale para Listas Collections int frequency(Coleccion col1, objeto obj) Devuelve el número de veces que el objeto obj se encuentra en la coleccion col1 Collections void reverse(Lista lis1) Invierte el orden de los elementos de la lista lis1 (el ultimo es el primero, penultimo segundo...) Solo vale para Listas Collections void rotate (Lista lis1, int desplaz) Rota los elementos de las lista lis1 tantas posiciones como desplaz indique. Solo vale para Listas Collections void shuffle (Lista lis1) Desordena aleatoriamente la lista lis1. Solo vale para Listas Collections void sort (Lista lis1) Ordena la lista lis1 ascendentemente, de acuerdo con su ordena natural. Solo vale para Listas Collections void sort (Lista lis1, Comparator comp) Ordena la lista lis1 ascendentemente, de acuerdo con el orden aplicado por la el objeto comp. Solo vale para Listas Collections void swap( Lista lis1, int posx, int posy) Intercambia los valores de los elementos de indices posx y posy, dentro de la lista lis1. Solo vale para Listas Clase Collections
  • 20. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Iterator ofrece métodos que permiten recorrer las colecciones con mejoras sobre un simple for o for-each. ๏ Todos los objetos de tipo colección implementan la interfaz Iterator. ๏ En particular, los borrados de elementos de una colección no se deben hacer con un for-each, pues puede fallar. Cuando se hace un for-each, java crea una copia ordenada de los elementos. Si se intenta eliminar elementos dentro del for-each, java se queja de que la copia que tenia previamente preparada puede quedar inconsistente, y da un ConcurrentModificationException Iterator Iterator 20 for (String nombre : lista2) { if (nombre.equals("Pedro")) { lista2.remove("Pedro"); } } ๏ Si se ejecuta este bucle puede producir un error como este : consola Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) En purismo, no se produce el error si sólo se efectua un remove dentro del for-each. El error se da si se efectuan dos o mas remove. Pero por control de errores en todas situaciones, no se debe usar un for-each para un borrado. Siempre es mejor usar iterator ๏ Para usar Iterator se aplica el método iterator() a una colección, y esto devuelve un objeto de tipo Iterator : Iterator objetoIterator = miColeccion.iterator(); ๏ Con dicho objeto que se pueden usar los siguientes métodos: CLASE DEVUELVE METODO DESCRIPCION Iterator boolean hasNext() Indica si hay más elementos a devolver de la lista, pero no devuelve ni coge ninguno Iterator object next() Devuelve el siguiente elemento de la lista, y avanza el puntero de la misma para que el próximo next() apunte al siguiente elemento. La lista inicialmente apunta al primer elemento. Da excepción NoSuchElementException si no hay elemento que leer Iterator object remove() Borra el elemento actual de la lista (el último recogido con una instrucción next() )
  • 21. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Si la colección es de tipo Lista, se puede usar ListIterator, que tiene más métodos que Iterator (hasPrevious( ), previous(), add(), set(), prevoiusIndex(), nextndex(), etc) Interfaz ListIteratorTemas avanzados • El uso de Iterator es muy sencillo. Se aplica el método iterator() a una colección, y esto devuelve un objeto de tipo Iterator : Iterator objetoIterator = unaColeccion.iterator(); • Con dicho objeto que se pueden usar los siguientes métodos: Iterator (II) 21 CLASE DEVUELVE METODOS (TODOS STATIC) DESCRIPCION Iterator boolean hasNext() Indica si hay más elementos a devolver de la lista, pero no devuelve ni coge ninguno Iterator object next() Devuelve el siguiente elemento de la lista, y avanza el puntero de la misma para que el próximo next() apunte al siguiente elemento. La lista inicialmente apunta al primer elemento. Da la excepción NoSuchElementException si no hay elemento que leer Iterator object remove() Borra el elemento actual de la lista (el último que se ha recogido con una instrucción next() ) CLASE DEVUELVE METODO DESCRIPCION ListIterator boolean hasPrevious() Indica, sin devolver, si hay elementos antes del actual ListIterator object previous() Devuelve el elemento previo al actual, y retrocede el puntero de recorrido de la colección ListIterator object add (object) Añade el objeto parámetro antes del elemento actual (el último que se ha recogido con una instrucción next() o previous() ). ListIterator object set( objeto) Sustituye el elemento actual por el pasado por parametro, ListIterator int nextIndex() Devuelve el indice del siguiente elemento ListIterator int previousIndex() Devuelve el indice del anterior elemento
  • 22. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Iterator (III) Ejemplos con Iterator (I) • Iterator se puede usar sin definir el tipo de dato a ordenar, o definiéndolo (como tipo genérico) • Se puede usar ListIterator para ordenar una lista al revés o con otras funcionalidad 22 // Creamos un ArrayList y algunos elementos para el ArrayList<String> miArrayList = new ArrayList<>(); miArrayList.add("HOLA"); miArrayList.add("ADIOS"); miArrayList.add("BUENAS"); miArrayList.add("HELLO"); miArrayList.add("CIAO"); // Listamos el contenido con un ITERATOR SIN TIPO Iterator iter = miArrayList.iterator(); while (iter.hasNext()) { String unElemento = (String) iter.next(); // necesita casting pues no se sabe el tipo System.out.println(" -> " + unElemento); } // Listamos el contenido con un ITERATOR CON TIPO GENERICO Iterator<String> iter2 = miArrayList.iterator(); while (iter.hasNext()) { String unElemento = iter2.next(); // ya no necesita casting System.out.println(" -> " + unElemento); } // Cambiamos los valores del ArrayList según los leemos // Podemos usar LISTITERATOR al ser un ArrayList la colección inicial ListIterator<String> liter = miArrayList.listIterator(); while (liter.hasNext()) { String unElemento = liter.next(); liter.set(unElemento + " con esto de apellido"); } // Tratandose de un LISTITERATOR, tengo métodos para recorrer LA LISTA AL REVES ListIterator<String> liter2 = miArrayList.listIterator(); while (liter2.hasPrevious()) { Object element = liter2.previous(); System.out.print(element + " ");
  • 23. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Iterator (IV) 23 / Sin embargo, no puedo borrar elementos con un for-each, esto DA ERROR, ConcurrentModificationException // for (String st : miArrayList) { // miArrayList.remove(st); // } // Aunque si solo quiero borrar un elemento, sí puede hacerse con for-each, // siempre que abandone el bucle tras borrar System.out.println("El array tiene antes de borrar " + miArrayList.size() + " elementos"); int kk = 0; for (String st : miArrayList) { if (st.equals("HELLO con esto de apellido")) { miArrayList.remove(st); break; // ya se sabe que usar breaks... no es de lo más elegante } } System.out.println("El array tiene ahora " + miArrayList.size() + " elementos"); // ASI QUE LA MANERA MÁS CORRECTA de eliminar elementos es usando Iterator. Aqui ejemplo con un ArrayList Iterator<String> ite8 = miArrayList.iterator(); while (ite8.hasNext()) { ite8.next(); ite8.remove(); } System.out.println("El array tiene ahora " + miArrayList.size() + " elementos"); // Y aqui ejemplo con un Map. Primero creamos el hashMap HashMap<Integer, String> miMapa = new HashMap<>(); miMapa.put(10, "Ana"); miMapa.put(20, "Mercedes"); miMapa.put(30, "Maria"); // Vemos primero que con for-each nos da error nuevamente por ConcurrentModificationException, esto NO vale // Set<Integer> lasClaves = miMapa.keySet(); // for (Integer jk : lasClaves) { // System.out.println("Borrando " + miMapa.get(jk)); // miMapa.remove(jk); // } // pero no da error con iterator Set<Integer> lasClaves = miMapa.keySet(); Iterator<Integer> ite4 = lasClaves.iterator(); while (ite4.hasNext()) { ite4.next(); ite4.remove(); } System.out.println("El mapa tiene ahora " + miMapa.size() + " elementos");
  • 24. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Cuidado con TreeSet y Comparator/Comparable Ordenación de colecciones Ordenación natural ๏ Se han visto varios tipos de colecciones de datos, ademas de los arrays. Contienen información, pero ¿pueden ordenarse los datos de estas colecciones? ¿Puedo ordenar los datos a mi interés? ๏ Para poder ordenar elementos, la JVM ha de poder comparar dos elementos entre si para determinar cual es mayor de los dos, y cual menor. ๏ Esta comparación puede hacerse de modo automático, depende del tipo de dato que se quiera ordenar: Tipos de datos con ordenación natural: Tipos que se pueden ordenar por un orden natural, como el que se da en los números o cadenas de texto (que se ordenan numéricamente o alfabéticamente, como los String o los int). También se incluyen aquí Date y otras clases donde Java aplica orden por defecto. Tipos de datos sin ordenación natural: Si se trata de un tipo de dato creado por nosotros, como una Persona, una Tarjeta, un Coche, y se le pide a la JVM que la ordene, ¿que criterio ha de seguir? Si le pido que ordene coches, ¿como lo ha de hacer? ¿por matricula? ¿por cilindrada? ¿por precio? Estos tipos de datos necesitan que se defina programáticamente como se van a ordenar 24 • Un TreeSet tiene sus elementos ordenados… ¡ pero necesita poder ordenarlos ! • Si son de tipo de dato con orden natural, como int, funciona sin más, pero como añadamos objetos a un TreeSet, HEMOS de decirle con un Comparator o Comparable cómo debe ordenar los objetos !! • El ejemplo de la derecha falla, por que no sabe como ordenar objetos de tipo Humano, • Mas adelante en el capitulo de Comparable y Comparator se da solución a este problema public class EjemploComparator { public static void main (String[] args) { Set<Humano> p = new TreeSet<> (); p.add (new Humano ("Luis", “Ruiz")); //ERROR } } class Humano { private String nombre; private String apellido; public Humano (String nombre, String apellido) { this.nombre = nombre; this.apellido = apellido; } }
  • 25. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Ordenación de colecciones: mecanismos Mecanismos de ordenación disponibles ๏ Ya se ha visto que si no se puede usar el mecanismo de ordenación natural, se debe acudir a usar las interfaces Comparator y Comparable para crear una ordenación propia. Veamos a continuación su uso. 25 1. Usar algoritmos propios de ordenación, que aplicados a arrays o colecciones, reubica los elementos de éstas según los criterios deseados. Uno de los ejemplos mas famosos es el algoritmo de la burbuja. Se explican algunos de estos algoritmos en las páginas de apéndices avanzados, al final del tema, pero no se detallan por ser algoritmos de diferente definición y paralelos a los contenidos del lenguaje Java. ๏ A la hora de ordenar colecciones, podemos actuar con alguna de estas soluciones : 2. Usando el método sort() de ordenación (en las clases Arrays y Collections). Este método funciona si: a) Si tipo de dato a ordenar puede usar un mecanismo natural que de ordenación, sólo hace falta usar el método sort() en la colección (tipos de datos primitivos, String, Date, etc) b) Si el tipo de dato a ordenar es un objeto sin orden natural, se debe usar Comparator y Comparable Ver más adelante 3. Usando el mecanismo de ordenación que por defecto traen alguna de las colecciones (como TreeSet). En estos casos también es necesario al igual que antes analizar que : a) Si tipo de dato a ordenar puede usar un mecanismo natural que de ordenación, no hace falta nada para ordenar la colección, está ordenada automáticamente b) Si el tipo de dato a ordenar es un objeto sin orden natural, se debe usar Comparator y Comparable
  • 26. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ La interfaz Comparable para que se use correctamente obliga a tres pasos: Implementar Comparable indicando el tipo de dato que se va a comparar: Implementar el método compareTo(obj1) (obligatorio al implementar Comparable) Ver en la página siguiente como escribir un método compareTo Finalmente, cuando la clase ya implemente Comparable puede ordenarse directamente en: ❖ Listas y arrays mediante los métodos Collections.sort() y Arrays.sort(). (Ejemplo alfa siguiente) ❖ También pueden ordenarse las claves en un mapa ordenado TreeMap (Ejemplo beta siguiente) ❖ Como elementos de un set ordenado TreeSet (sin necesidad de métodos). (Ejemplo delta siguiente) Comparable Interfaz Comparable 26 class Persona implements Comparable<Persona> { Comparable es una interfaz genérica, hay que poner la clase que se va a comparar Comparable y Comparator ๏ Comparable y Comparator se usan para ordenar colecciones de objetos que no tienen orden natural ๏ La diferencia entre una y otra es que con Comparable sólo se puede usar un criterio de ordenación en la colección, mientras que con Comparator se puede ordenar la colección, si es necesario, de diversas formas
  • 27. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ El método recibe como parámetro un objeto con el que comparar , de forma que la comparación se realizará del objeto en si (this) con el objeto pasado como parámetro. compareTo( obj1 ) ๏ El método debe devolver un valor entero que será según los casos; ‣ un número negativo si el objeto-base (this) es menor que el parámetro ‣ un cero si es igual que el parámetro ‣ un número positivo si el objeto-base es mayor que el parámetro. ๏ Por lo general, se usan uno o varios atributos de la clase para efectuar la comparación entre objetos y por lo tanto la ordenación. Aquí podemos tener varios casos, según el tipo de dato a comparar : Comparable: compareTo 27 class Persona implements Comparable<Persona> { String nombre; public Persona (String n) { this.nombre = n; } @Override // metodo compareTo con objetos public int compareTo (Persona p) { return nombre.compareTo (p.nombre); } } a) Que el atributo sea un objeto, como String o Date. Para obtener el valor de retorno, usamos el propio método compareTo del objeto b) Que el atributo sea un tipo primitivo numérico. Se puede hacer restando los valores a comparar (primero el propio y luego el del parámetro): En la clase Persona, si se ordena por el nombre que es String, se usa compareTo de los nombres para que nos den directamente el valor a devolver: También se puede hacer varios if que devuelven -1, 0 o 1 segun lo que se desee class Persona implements Comparable<Persona> { int edad; public Persona (int s) { this.edad = e; } @Override // metodo compareTo con primit. public int compareTo (Persona p) { return this.edad - p.edad; } } método compareTo()
  • 28. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Ejemplos de comparable Ejemplos de usos de Comparable 28 public static void main (String[] args) { Set<Persona> p = new TreeSet<Persona> (); p.add (new Persona ("Luis", "Ruiz")); p.add (new Persona ("Pablo", "Martinez")); p.add (new Persona ("Alberto", "Lopez")); p.add (new Persona ("Cesar", "Perez")); for (Persona persona : p) System.out.println (persona); } public static void main (String[] args) { Map<String, Persona> p = new TreeMap<> (); p.put ("Ruiz", new Persona ("Luis", "Ruiz")); p.put ("Martinez",new Persona ("Pablo", "Martinez")); p.put ( "Lopez",new Persona ("Alberto", "Lopez")); p.put ("Perez", new Persona ("Cesar", "Perez")); for (String ape : p.keySet ()) System.out.println (ape); } public static void main (String[] args) { List<Persona> p = new ArrayList<Persona> (); p.add (new Persona ("Luis", "Ruiz")); p.add (new Persona ("Pablo", "Martinex")); p.add (new Persona ("Alberto", "Lopez")); p.add (new Persona ("Cesar", "Perez")); Collections.sort (p); for (Persona persona : p) System.out.println (persona); } class Persona implements Comparable<Persona> { private String nombre; private String apellido; public Persona (String nombre, String apellido) { this.nombre = nombre; this.apellido = apellido; } @Override public int compareTo (Persona p) { return nombre.compareTo (p.nombre); } public String toString(){ return nombre+" "+apellido; } } consola Alberto Lopez Cesar Perez Luis Ruiz Pablo Martinez Comparable con ArrayList y Collections.sort() consola Lopez Martinez Perez Ruiz Comparable con TreeMap y sin mas metodos. Solo quedan ordenadas las claves, pues no pueden quedar ordenados los valores, y que las claves se autoordenan por que son una Set en si mismas, y de un tipo de orden natural Comparable con TreeSet, sin necesidad de usar métodos consola Alberto Lopez Cesar Perez Luis Ruiz Pablo Martinez ★ Hay que tener en cuenta que cuando las comparaciones son con objetos, si se comparan objetos de clases diferentes, puede lanzar un ClassCastException. ★ Se puede implementar la interfaz sin tipo genérico, definiendo solamente implements Comparable. En este caso, será Object el parámetro del método compareTo (compareTo (Object ob) ) y dentro del método hay que tener cuidado de hacer los cast necesarios !!
  • 29. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Comparable sólo puedo establecer un método de ordenación, pues solo puedo escribir un método compareTo, ya que este no es sobrecargable (p.e. la clase Persona del ejemplo anterior, si se ordena por nombre, luego no se puedo intentar ordenar por edad) ๏ Comparator si permite varias ordenaciones, y su uso es muy parecido al de Comparable. Pasos para usarla: No se va a tener que cambiar nada en la clase que vamos luego a comparar (Personaje), a diferencia de Comparable Se ha de crear una clase nueva, propia, que debe implementar Comparator, indicando el tipo de dato que se va a comparar: En esta clase nueva creada, hay que implementar el método compare(obj1, obj2) (nos obliga Comparator a implementarlo). Ver en la página siguiente como escribir la clase con su método compare() Esta clase nueva creada, que implementa Comparator, podemos usarla para ordenar de estos modos: ❖ Listas y arrays mediante los métodos Collections.sort() y Arrays.sort(), añadiendo un segundo parametro, ademas de la colección a ordenar, un objeto de la clase-comparator (Ejemplo alfa) ❖ También pueden ordenarse las claves en un mapa ordenado TreeMap (Ejemplo beta) ❖ Como elementos en un set ordenado TreeSet, para lo cual debemos crear un un objeto de la clase- comparator que se le pasa como parámetro al constructor de la colección, a la hora de crearla (Ejemplo gamma) Comparator Interfaz Comparator 29 class MiClaseParaOrdenarPorNombre implements Comparator<Persona> {...}
  • 30. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Nos obliga Comparator a implementarlo dentro de la clase que creemos. Es muy parecido al compareTo() que vimos en Comparable: ๏ El método recibe esta vez como parámetros dos objetos con los que hacer la comparación: compare(obj1, obj2) ๏ El método debe devolver un valor entero con la misma casuística que se usa en Comparable; ‣ un número negativo si el parámetro1 es menor que el parámetro2, ‣ un cero si son iguales ambos parámetros ‣ y un número positivo si el parámetro1 es mayor que el parámetro2,. ๏ Por lo general, también como en Comparable se usan uno o varios atributos de la clase para efectuar la comparación, y nuevamente habrá dos casos, según el tipo de dato que usemos para ordenar: Comparator: compare() 30 método compare() class ModeloComparador implements Comparator<Humano> { @Override public int compare (Humano p1, Humano p2) { return (p1.nombre.compareTo (p2.nombre)); } } class ModeloComparador2 implements Comparator<Humano> { @Override public int compare (Humano p1, Humano p2) { return (p1.edad - p2.edad); } } a) Que el atributo sea un objeto, como String o Date. Para obtener el valor de retorno, usamos el propio método compareTo del objeto b) Que el atributo sea un tipo primitivo numérico. Se puede hacer restando los valores a comparar (de ambos parámetros):
  • 31. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Comparator: ejemplos Ejemplos de usos de Comparator 31 public static void main (String[] args) { ModeloComparador modcom3 = new ModeloComparador (); Set<Humano> ppp = new TreeSet<> (modcom3); ppp.add (new Humano ("Luis", 23)); ppp.add (new Humano ("Pablo", 22)); ppp.add (new Humano ("Alberto", 18)); ppp.add (new Humano ("Cesar", 34)); for (Humano serhumano : ppp) System.out.println (serhumano.nombre); } public static void main (String[] args) { List<Humano> p = new ArrayList<Humano> (); p.add (new Humano ("Luis", 23)); p.add (new Humano ("Pablo", 22)); p.add (new Humano ("Alberto", 18)); p.add (new Humano ("Cesar", 34)); ModeloComparador modcom = new ModeloComparador (); Collections.sort (p, modcom); for (Humano serhumano : p) System.out.println (serhumano.nombre); } class Humano { public String nombre; public int edad; public Humano (String nombre, int edad) { this.nombre = nombre; this.edad = edad; } public String toString () { return (nombre + " " + edad); } } public static void main (String[] args) { // Map<Humano, String> ppp = new TreeMap<> (); // ESTO DA ERROR // pues intenta autoordenar la clave, que no es de orden natural ModeloComparador modcom2 = new ModeloComparador (); Map<Humano, String> pp = new TreeMap<> (modcom2); pp.put (new Humano ("Luis", 23), "Ruiz"); pp.put (new Humano ("Pablo", 22), "Martinez"); pp.put (new Humano ("Alberto", 18), "Lopez"); pp.put (new Humano ("Cesar", 34), "Perez"); for (Humano h : pp.keySet ()) System.out.println (h.edad); } Ejemplo alfa: Comparator con ArrayList y Collections.sort() pero añadiendo la clase-comparator en el sort() Ejemplo gamma: Comparator con TreeSetsin necesidad de usar métodos, pero añadiendo la clase-comparator en el constructor de la colección Ejemplo beta: Comparator con TreeMap y sin más metodos, pero añadiendo la clase-comparator en el constructor de la colección Advertir que lo que queda ordenado son las claves, pues no pueden quedar ordenados los valores, y que las claves NO se autoordenan por que son una Set en si mismas, pero NO de un tipo de orden natural consola Alberto Lopez Cesar Perez Luis Ruiz Pablo Martinez consola 18 22 23 34 consola Alberto Cesar Luis Pablo
  • 32. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Resumen ordenación: Arrays Resumen: si se necesita ordenar Arrays Para ordenar arrays se puede usar Arrays.sort() 1. Si son datos con orden natural, ejecutando simplemente Arrays.sort( listaaordenar) 2. Si son datos objetos: a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1), y ademas ejecutar Arrays.sort(listaaordenar) b) Usar un objeto de una clase que implemente la interfaz Comparator en el método Arrays.sort(arrayaordenar,objetoComparator) 3. Para ordenar descendentemente, usar Arrays.sort(arrayaordenar, Collections.reverseOrder()) (No válido para primitivos) 32 System.out.println ("-- Ordenando ARRAYS con tipos primitivos"); String[] p = new String[3]; p[0] = "Luis"; p[1] = "Pablo"; p[2] = "Alberto"; // usando el metodo Arrays.sort(array) // vale para cualquier tipo primitivo y String Arrays.sort (p); for (String mm : p) { System.out.println (mm); } System.out.println ("----------"); char[] h = new char[3]; h[0] = 'w'; h[1] = 'a'; h[2] = 't'; Arrays.sort (h); for (int mm : h) { System.out.println ((char) mm); } System.out.println ("—- Ordenando ARRAYS con objetos"); Humano[] listaper = new Humano[3]; listaper[0] = new Humano ("Juan", 32); listaper[1] = new Humano ("Ana", 21); listaper[2] = new Humano ("Marta", 46); Arrays.sort (listaper); // Arrays.sort(array) vale para objetos, for (Humano mm : listaper) { // sólo si tienen compareTo en la clase System.out.println (mm.nombre); // que se ordena y se implementa Comparable } //Clase Humano class Humano implements Comparable<Humano> { String nombre; int edad; public Humano (String n, int e) { this.nombre = n; this.edad = e; } @Override // metodo compareTo sencillo public int compareTo (Humano p) { return nombre.compareTo (p.nombre); } } consola -- Ordenando ARRAYS con tipos primitivos Alberto Luis Pablo ---------- a t w ---------- Ana Juan Marta
  • 33. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Resumen: si se necesita ordenar Listas Para ordenar Listas, da igual ArrayList o LinkedList o Vector , se usa Collections.sort() 1. Si son datos con orden natural, ejecutando simplemente Collections.sort( listaaordenar) 2. Si son datos objetos: a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1), y ademas ejecutar Collections.sort(listaaordenar) b) Usar un objeto de una clase que implemente la interfaz Comparator en el método Collections.sort(arrayaordenar,objetoComparator) 33 System.out.println ("-- Ordenando un ArrayList de tipos primitivos"); // necesitamos de un Collections.sort() List<String> p1 = new ArrayList<> (); p1.add ("Luis"); p1.add ("Pablo"); p1.add ("Alberto"); Collections.sort (p1); for (String nombre : p1) System.out.println (nombre); System.out.println ("-- Ordenando un ArrayList de objetos"); // necesitamos de un Collections.sort() List<Humano> listaper2 = new ArrayList<> (); listaper2.add (new Humano ("Juan", 32)); listaper2.add (new Humano ("Ana", 21)); listaper2.add (new Humano ("Marta", 46)); Collections.sort (listaper2); for (Humano pp : listaper2) System.out.println (pp.nombre); //Clase Humano class Humano implements Comparable<Humano> { String nombre; int edad; public Humano (String n, int e) { this.nombre = n; this.edad = e; } @Override // metodo compareTo sencillo public int compareTo (Humano p) { return nombre.compareTo (p.nombre); } } consola -- Ordenando ArrayList con tipos primitivos Alberto Luis Pablo ---------- Ana Juan Marta Resumen ordenación: Listas
  • 34. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Resumen: si se necesita ordenar Maps Para ordenar Maps, solo podremos ordenar las claves, nunca los valores • Con HashMap no están ordenados ni las claves ni los valores • Con TreeMap para ordenar las claves : 1. Si las claves son datos con orden natural, están ordenadas implícitamente 2. Si las claves son de objetos: a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1) b) Usar un objeto de una clase que implemente la interfaz Comparator en el constructor del TreeMap: 34 ClaseComparador miclas = new ClaseComparador (); Map<Humano, String> pp = new TreeMap<> (miclas); consola ---- Ordenando un HashMap por valores primitivos Alberto Pablo Norberto Luis -- Ordenando un HashMap por claves primitivas 2 3 4 -- Ordenando un TreeMap por valores Pablo Alberto Luis Clave : 2 Valor :Pablo Clave : 3 Valor :Alberto Clave : 4 Valor :Luis System.out.println ("-- Ordenando un HashMap por valores primitivos"); // no se puede usar Collections.sort() // con lo que un HashMap directamente NO puede ordenarse Map<Integer, String> p5 = new HashMap<> (); p5.put (44, "Luis"); p5.put (22, "Pablo"); p5.put (33, "Alberto"); p5.put (11, "Norberto"); for (String nombre : p5.values ()) System.out.println (nombre); System.out.println ("-- Ordenando un HashMap por claves primitivas"); // no hace falta usar Collections.sort() // ya que el conjunto de claves es un set autoordenado Map<Integer, String> p2 = new HashMap<> (); p2.put (4, "Luis"); p2.put (2, "Pablo"); p2.put (3, "Alberto"); for (int nombre : p2.keySet ()) System.out.println (nombre); System.out.println ("-- Ordenando un TreeMap por valores "); // no hace falta usar Collections.sort() // ya que el TreeSet garantiza orden por claves (no por por valores) Map<Integer, String> p27 = new TreeMap<> (); p27.put (4, "Luis"); p27.put (2, "Pablo"); p27.put (3, "Alberto"); for (String nombre : p27.values ()) System.out.println (nombre); Iterator iterator = p27.keySet().iterator(); while (iterator.hasNext()) { Object key = iterator.next(); System.out.println("Clave : " + key + " Valor :" + p27.get(key)); } Resumen ordenación: Maps
  • 35. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Resumen: si se necesita ordenar Sets Para ordenar Sets, depende de que clases usemos: • Con HashSet no se puede ordenar sus valores • Con TreeSet 1. Si son datos con orden natural, están ordenadas implícitamente 2. Si son datos de objetos: a) Usar la interfaz Comparable en la clase que se ordena, sobrescribiendo compareTo(obj1) b) Usar un objeto de una clase que implemente la interfaz Comparator en el constructor del TreeSet: 35 System.out.println ("-------------- con un HashSet"); // no se puede ordenar un hashSet() Set<String> p3 = new HashSet<> (); p3.add ("Luis"); p3.add ("Pablo"); p3.add ("Alberto"); for (String nombre : p3) System.out.println (nombre); System.out.println ("-------------- con un TreeSet"); // no hace falta usar Collections.sort() // ya un treeset esta autoordenado Set<String> p35 = new TreeSet<> (); p35.add ("Luis"); p35.add ("Pablo"); p35.add ("Alberto"); for (String nombre : p35) System.out.println (nombre); consola ----------- con un HashSet Alberto Luis Pablo ----------- con un TreeSet Alberto Luis Pablo ClaseComparador miclas = new ClaseComparador (); Set<Humano> pp = new TreeSet<> (miclas); Resumen ordenación: Sets
  • 36. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Puntos resumen más importantes en temas de ordenación; • Los valores de TreeSet están ordenados implícitamente, si son datos con orden natural • Si hay que ordenar objetos sin orden natural, hemos de usar siempre “comparadores” (Comparator o Comparable) • Los valores de arrays, List y Sets se puede ordenar mediante programación con métodos sort(), añadiendo Comparable, o ambas cosas • Los valores de los Map no se pueden ordenar, como mucho, las claves. • Los valores de los HashXXX no se pueden ordenar. Solo se pueden ordenan las claves de un HashMap (y es por que las claves son un Set en si mismas, si se extraen y ordenan por mecanismos de ordenación de un Set) Cuadro comparativo colecciones Resumen: Comparador de colecciones ARRAYS LISTS MAPS SETS array ArrayList HashMap TreeMap HashSet TreeSet Descripcion lista fija de cosas lista de cosas grupo de cosas con indice único grupo de cosas con indice único grupo de cosas únicas grupo de cosas únicas Redimensionable no si si si si si Permite duplicados si si si si no no acceso por indice si si no no no no acceso por clave propia no no si si no no Ordenación implícita (sin necesidad de codificación expresa) no no no SI, sólo las claves y solo si son con orden natural no SI, solo si son con orden natural Ordenación programada (añadiendo Comparable u otros métodos) Por “comparadores” se entiende uso de Comparable o Comparator SI, con Arrays.Sort() y además “comparadores” para objetos SI, con Collections.Sort() y además “comparadores” para objetos no SI, sólo las claves y además con “comparadores” para objetos no SI, con “comparadores” para objetos 36 ๏ Esta tabla ofrece una comparación de las características de los principales tipos de colección.
  • 37. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Elegir TreeSet, sin tener que hacer nada más, los elementos están ordenados Cuadro de elección de colección a usar Resumen: Elegir qué colección usar si hay que ordenarla El contenido de la colección tiene orden natural (no tiene como contenido objetos de clases propias) El contenido de la colección tiene objetos de clases propias Elegir un array y ordenarlo por Arrays.sort(array), o elegir una List y ordenar por Collections.sort(coleccion), NO Tiene elementos repetidos En la clase que compone la colección, implementar Comparable<MiClase> y sobrescribir compareTo(MiClase c) Se necesita ordenar la colección por más de un criterio de ordenación Se necesita un único criterio de ordenación Elegir TreeSet, y en su constructor, añadir como parámetro un objeto de MiOrden: Elegir un array y ordenarlo por Arrays.sort(array, MiOrden), o elegir una List y ordenar por Collections.sort(coleccion, MiOrden) Tiene elementos repetidos NO Tiene elementos repetidos Tiene elementos repetidos class Figura implements Comparable<Figura> { private String nombre ; public int largo ; public String getNombre() { return nombre; } public int compareTo(Figura f) { return nombre.compareTo (f.getNombre ()); } } Para cada criterio de ordenación, crear una clase nueva (p.e. MiOrden) que implemente Comparator<MiOrden> y sobrescribir compare(MiOrden c, MiOrden d) class MiOrden implements Comparator<Figura>{ public int compare (Figura a, Figura b) { return a.getNombre().compareTo(b.getNombre ()); } } class MiOrden2 implements Comparator<Figura>{ public int compare (Figura a, Figura b) { return a.largo - b.largo; } } Set<Figura> a = new TreeSet<>(new MiOrden()); List<Figura> b = new ArrayList<>(); Collections.sort (b,new MiOrden()); Figura [] c = new Figura [5]; Arrays.sort (c , newMiOrden()); List<Figura> b = new ArrayList<>(); Collections.sort (b); Figura [] c = new Figura [5]; Arrays.sort (c); 37
  • 38. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Cuidado con TreeSet com Comparator y Comparable Aunque ya se ha dicho, es necesario ahondar en el uso de los TreeSet, pues suele ser pregunta trampa de muchos exámenes. Un TreeSet tiene sus elementos ordenados, pero necesita poder ordenarlos! No es opcional, tiene que saber ordenarlos Si son de tipo de dato con orden natural, como int, funciona sin mas, pero si añadimos objetos a un TreeSet, hay de decirle con un Comparator o Comparable como debe ordenar los objetos !! En estos ejemplos, el primero de la derecha funciona, pero el segundo falla. El primero contiene String, el otro objetos de tipo Humano... y falla al no saber ordenarlo: Si queremos que funcione, hemos de hacer que la clase Humano implemente Comparable, o crear una clase de ordenación con Comparator y se añada a la construcción del TreeSet como parámetro del constructor. Esta segunda es la solución que se incluye aqui abajo(se ha marcado en rosa la inclusión de un objeto de la “clase ordenadora” en el constructor del TreeSet) TreeSet con Comparator y Comparable 38 public class EjemploComparator { public static void main (String[] args) { Set<String> p1 = new TreeSet<> (); // OK, BIEN p1.add ("Luis"); Set<Humano> p2 = new TreeSet<> (); p2.add (new Humano ("Luis", 32 )); //ERROR } } class Humano { String nombre; int edad; public Humano (String nombre, int edad) { this.nombre = nombre; this.edad = edad; } } class EjemploComparator { public static void main (String[] args) { Set<Humano> p = new TreeSet<> (new modeloComparador ()); p.add (new Humano ("Luis", 23)); p.add (new Humano ("Alberto", 18)); p.add (new Humano ("Cesar", 34)); for (Humano serhumano : p) System.out.println (serhumano.nombre); } } class modeloComparador implements Comparator<Humano> { @Override public int compare (Humano p1, Humano p2) { return (p1.edad - p2.edad); } }
  • 39. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones equals y hashCode (I) equals() y hashCode() ๏ hashCode() y equals() son dos métodos directamente heredados de Object. Tienen muchas particularidades que los hacen necesitar un apartado especial para ellos: 1. hashCode() ✴ es un método que devuelve un integer, que es un identificador único del objeto. ✴ La implementación por defecto de hashCode() simplemente convierte la dirección de memoria del objeto en un numero int 2. equals() ✴ compara dos objetos para ver si son o no iguales. ✴ Si no se sobrescribe, para decidir si los dos objetos son iguales comprueba simplemente las referencias de ambos objetos, esto es, los compara con == . ๏ Ambos se usan en la mayoría de las colecciones para ver si un elemento existe en dicha colección, y para borrarlo, especialmente en las colecciones que son de tipo Hash (HashTable, HashMap or HashSet.) Cuando se busca un elemento en una colección, se intenta primero analizar si son iguales mirando si devuelve lo mismo el método hashCode(). Como esto puede ocurrir con varios elementos (ver parte avanzada para mas detalle), además de eso, posteriormente se mira si da true el método equals() ๏ Por eso, por que se ejecutan en “comanda”, tienen un “contrato particular” que obliga a que, si se decide sobrescribir equals() o hashCode() , deben entonces sobrescribirse AMBOS ๏ Pero en realidad, si ya existen, heredados, ¿por que habría necesidad de sobrescribirlos? Por que la igualdad de los objetos con equals() (mirar solo su referencia) es muy pobre, y puede dar lugar a sorpresas si el uso no esta muy controlado (ver apéndice avanzado más adelante) 39
  • 40. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Sobrescribir equals() Cómo sobrescribir equals() ๏ Como ya se ha dicho, la implementación por defecto de equals() simplemente compara las direcciones de memoria de los objetos, sus referencias. ๏ Esto quiere decir que deberemos sobrescribir equals() para hacerlo a nuestro gusto siempre que: ‣ Sepamos que vamos a realizar comparaciones con objetos de nuestra clase, y por lo tanto, lo mas lógico será usar el propio método equals() para ello ‣ Sepamos que se van a crear colecciones con objetos de mi clase, y estas colecciones pueden ser de tipo Hash 40 // El método es public y recibe como parámetro un tipo Object, si no, no estaria // sobrescribiendo equals() public boolean equals (Object obj) { // Comprueba si la referencia del objeto obj y el objeto que llama a equals // son las mismas, en cuyo caso, son iguales los objetos, y devuelve true if (this == obj) return true; // Comprueba si la referencia del objeto parametro es null // en cuyo caso, devuelve false directamente if (obj == null) return false; // Comprueba si la clase a la que pertenece el objeto parametro y // el objeto que llama a equals son distintas, y devuelve false en tal caso if (getClass () != obj.getClass ()) return false; // Crea un objeto de tipo MiClaseCoche con un casting al // parámetro recibido, para poder usarlo ahora despues MiClaseCoche other = (MiClaseCoche) obj; // Comparamos los atributos que queramos de los dos objetos // para dar true o false a la comparacion if (!marca.equals (other.marca)) return false; if (matricula == null) { if (other.matricula != null) return false; } else if (!matricula.equals (other.matricula)) return false; return true; } Los IDE pueden crear automáticamente el metodo, y en el código que crean puede haber pistas de una buena operativa a seguir con este tipo de análisis para comparar objetos. Aunque si no se quiere ser tan exigente, se pueden hacer menos análisis, eliminando algunos de los que se muestran en el ejemplo:
  • 41. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Sobrescribir equals() ๏ El mecanismo normal para hacer un equals() en nuestra clase es comparar algunos de sus atributos. ๏ La comparación debe ser a gusto del usuario, buscando alguna regla que de true o false según las necesidades. En este ejemplo, dos coches no serán iguales comparando sus matriculas, sino que se considerará que son iguales si tienen la misma marca y modelo. Este es el equals() “reducido: 41 @Override public boolean equals (Object obj) { if (! ( obj instanceof MiClaseCoche)) return false; // Crea un objeto de tipo MiClaseCoche con un casting al // parámetro recibido, para poder usarlo ahora despues MiClaseCoche otro = (MiClaseCoche) obj; // Comparamos los atributos que queremos if ((marca.equals (otro.marca)) && (modelo.equals (otro.modelo)) { return true; } else { return false; } } Mucho cuidado a la hora de sobrescribir equals: • boolean equals(Objeto o) {...} Esto NO sobrescribe equals(), el método debe ser declarado como public. • public boolean equals(Demo o) {...}. Esto NO sobrescribe equals(), el método necesita un parámetro Object • Reflexivo: Para un valor dado de un objeto x, x.equals(x) debe dar true. • Simetrico: Dados unos objetos x y z, x.equals(z) debe dar true estrictamente sí (sí y solo sí) z.equals(x) es true. • Transitivo. Dados unos objetos w, x y z, si w.equals(x) da true y x.equals(z) da true, entonces w.equals(z) debe dar true. • Consistente: Dados unos objetos x y z, varias llamadas a x.equals(z) deben dar consistentemente true o false, si es que los valores utilizados para la comparación de los objetos non ha sido modificados. • Para cualquier caso en que x no sea null, x.equals(null) debe dar false. Reglas que ha de seguir el método equals()Temas avanzados
  • 42. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Sobrescribir hashCode() ๏ La implementacion por defecto de hashCode() (la que se hereda de Object) simplemente convierte la dirección de memoria del objeto en un numero int ๏ Si sobrescribimos hashCode, para que tenga mas funcionalidad, debemos intentar que el método devuelva enteros diferentes para objetos diferentes ๏ No es correcto usar funciones random para calcular un hashCode(), pues pueden no devolver el mismo resultado a iguales llamadas en una misma ejecucion del programa. ๏ Normalmente se sobrescribe hashCode() usando el hashCode() de alguno o varios atributos ๏ Algunos ejemplos; Cómo sobrescribir hashcode() 42 @Override public int hashCode () { final int prime = 31; int result = 1; result = prime * result + edad; return result; } @Override public int hashCode () { return this.nombre.hashCode(); } @Override public int hashCode () { return this.nombre.hashCode() + this.edad; } • Si objeto1 y objeto2 son iguales, según el método equals(), han de serlo siempre también con el método hashcode() • Si objeto1 y objeto2 son iguales, según el método hashchde(), no tienen por que ser iguales con el método equals() Reglas que ha de seguir el método hashcode()Temas avanzados
  • 43. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Cuando se vieron los principales principios de POO, se dejó para este momento la explicación del principio de desacoplamiento. ๏ Este principio facilita el que cuando se programa un método o una clase, no tiene ésta que depender de un tipo específico de datos, sino que use conceptos como Interfaz para que sea el valor que devuelva un método, y aprovechándose del polimorfismo, permitir que en el futuro pueda tener independencia a la hora de cambiar mis programas. ๏ Por ejemplo, List es una interfaz (implementada en todas las colecciones de listas, entre otras por Arraylist). En este ejemplo de método, deseo devolver una lista. Si lo construyo así: En este caso, no devuelvo un Arraylist, sino un List. Cualquiera que llame a este método obtiene un List, que lo puede convertir a Arraylist o a LinkedList a lo que quiera. Y además, aun más importante, si en el futuro necesito cambiar mi método y dentro de él no trabajar con Arraylist, puedo hacer los cambios que sean por otra clase, y la capa que llame a mi método no se ve afectada (siempre que la nueva clase implemente también List, claro) Desacoplamiento Desacoplamiento 43 public List<persona> obtener () { ArrayList<Persona> aa … …. return aa }
  • 44. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones ๏ Usar el método estático asList() de la clase Arrays, que devuelve un objeto de tipo List Formato: lista objetolista = Arrays.asList( unarray ); ๏ Cuidado : ambos objetos quedan “enlazados” por una referencia al mismo conjunto de objetos, lo que significa que los cambios que se realicen en la colección se efectúan automáticamente en el array, y viceversa. ๏ Usar el método estático toArray() de la interfaz List, que devuelve un array de Object Formato: tipodedatodelarray unarray = Collections.toArray( unacoleccion) ๏ Cuidado : el array es una copia del conjunto de datos de la colección, por lo que los cambios que se realicen en la colección NO afectan al array, ni viceversa. Conversiones Colecciones - Arrays Convertir un array en una colección Convertir una colección en un array 44 ArrayList<String> ciudades = new ArrayList<>(); ciudades.add("Madrid"); ciudades.add("León"); ciudades.add("Granada"); Object [ ] arrayciu = ciudades.toArray(); String [ ] ciudades = {"Madrid","Leon","Granada"}; List<String> listaciu = Arrays.asList(ciudades);
  • 45. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones Avanzado 45 - Una colección tipo hash guarda sus elementos en una estructura indexada. - Para saber que índice tiene cada elemento (al insertarlo o consultado o borrarlo) se aplica al mismo una función hash que indica donde se encuentra o se va a colocar el elemento (en Java la función hash que se aplica es el resultado de hashcode()) - Una colección hash es muy eficiente en las búsquedas, pues puede hacerlas binarias. - Sin embargo, una función hash no puede asegurar que no de el mismo resultado para dos elementos. Esto provoca “colisiones” - Paso a paso, cuando se busca un elemento en una tabla hash, por lo tanto, se efectúa este proceso: a) se calcula su posición con la función hash, lo que determina un cierto “area” donde debe estar (en java se calcula este “área” con el método hashcode() b) Se busca el elemento en dicha área c) Se mira si hay mas elementos en esa área (que deben entonces tener la misma clave hash) d) Si existen varios, se promueve algún mecanismo de solución de la “colisión” e) El mecanismo que usa Java es aplicar ahora equals() entre los objetos del área para determinar cuál es el deseado. Así vemos el uso combinado de hashcode() y equals() en colecciones tipo hash Importantes a tener en cuenta con hashcode() y equals(); - Dos objetos iguales deben producir el mismo resultado al aplicar equals(). Sin embargo, objetos diferentes pueden producir equals() iguales - El método equals() provee comparación “profunda” al comparar dos objetos, mientras que el operador == provee una comparación "shallow" (superficial) (Ver capitulo de objetos, apartado de Temas Avanzados) Colecciones Hash mas en detalleTemas avanzados
  • 46. TemariodecursoJavaSE©IñakiMartín 11.- Colecciones • Analicemos despacio los “sysout” de este ejemplo: • ¿Qué ha pasado? Pues que no se han encontrado los elementos en la colección. Si se hubiera usado sí se habría encontrado el elemento, pero usando no se encuentra, pues equals() no da true, al no ser los mismos objetos, al tener distinta referencia • Por eso es conveniente, si se va a trabajar con colecciones, sobrescribir los métodos equals() y hashCode() de todas las clases que intervengan como valor de ordenación. Cuando faltan equals() y hashcode() ....Temas avanzados equals y hashCode (II) /* — Ejemplo de ejecución del programa: Tamaño del conjunto: 5 miConjunto.contains( new Actor(25)): false miConjunto.remove( new Actor(24): false Tamaño otra vez del conjunto: 5 */ 46 System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (new Actor (24))); System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (act2)); Actor act1 = new Actor (23); Actor act2 = new Actor (24); Actor act3 = new Actor (25); Actor act4 = new Actor (26); Actor act5 = new Actor (27); Set<Actor> miConjunto = new HashSet<Actor> (); miConjunto.add (act1); miConjunto.add (act2); miConjunto.add (act3); miConjunto.add (act4); miConjunto.add (act5); System.out.println ("Tamaño del conjunto: " + miConjunto.size ()); System.out.println ("miConjunto.contains( new Actor(25)): " + miConjunto.contains (new Actor (25))); System.out.println ("miConjunto.remove( new Actor(24): " + miConjunto.remove (new Actor (24))); System.out.println ("Tamaño otra vez del conjunto: " + miConjunto.size ());