U9 – API Collections y Generics En esta unidad vamos a estudiar las múltiples maneras que ofrece el lenguaje Java para tratar con conjuntos de elementos, colecciones o listados. Veremos cuando es conveniente utilizar cada uno, y como obtener valores de estos conjuntos. Al finalizar el estudio de estas lecciones serás capaz de: • Conocer las implementaciones de Collections. • Utilizar la interfaz Map. • Manejar las colecciones tradicionales. • Utilizar el Comparable y Comparator para ordenar resultados. • Refactorizar código no genérico. • Examinar el bucle loop mejorado. • Escribir un programa que permita la iteración de un listado. 1 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L1 – Implementaciones del interface Collections El propio lenguaje Java proporciona un conjunto de clases e interfaces que nos facilitan el uso de colecciones de datos. La clase más general es el “Interface collections” que mediante el uso del polimorfismo nos proporciona multitud de implementaciones diferentes. Estas clases se encuentran dentro del paquete java.util y recientemente se puede hacer uso genérico de ellas. El uso de Collections nos proporciona ciertas ventajas frente al uso tradicional de Arrays: • Cambiar el tamaño dinámicamente • Permite ordenación • Permite la inserción y eliminación de datos ¿Qué es el uso genérico? Este término en java es bastante reciente (desde la versión 1.5, actualmente 1.6) Antes cuando introducíamos objetos en una colección independientemente de que tipo fueran se almacenaban en la colección como “Object”. Al recuperarlo debíamos realizar un casting al tipo de objeto que era antes de entrar en la colección. Actualmente se permite el uso de “Colecciones Tipadas” o generics en las que podemos especificar qué tipo de objeto compondrá la colección. Esta característica le permite al compilador lanzar un error en tiempo de compilación si intentamos introducir un objeto de un tipo incompatible, evitando errores en la ejecución del programa. Recuerde El interfaz Collections y sus implementaciones genéricas permitirán tratar conjuntos de elementos siempre del mismo tipo. 2 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Un esquema general del interface Collections es: Interface Collection Es la interface más básica o genérica de la que todos implementan. Las características de Collection en Java son: • Lo elementos que componen la colección se pueden iterar o recorrer • Se puede conocer el tamaño de la colección El resto de colecciones irán añadiendo más características a estas definidas. Recuerde Dado que Collection es un interface no podremos crear objetos de este tipo, sino que todas las colecciones de una clase tienen las operaciones que ofrece el interface Collection. 3 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Las operaciones principales que ofrece este interface son: • add(Objeto) Æ Añade un elemento. • iterator() Æ Permite recorrer los elementos de uno en no obteniendo sus propiedades • size() Æ Muestra la cantidad de elementos de la colección. • contains(Objeto) Æ Obtiene si un elemento está ya dentro de la colección. Interface List Este interface es una implementación de Collection por lo que además de sus propias características añade: • El orden de los elementos es arbitrario • Permite acceder a los elementos por orden. Los métodos que añade son: • get(int i) Æ Obtiene el elemento en la posición determinada. • set(int i, Object t) Æ Coloca el objeto en una posición determinada. Interface Set El interface set, tiene las mismas características que Collections pero añade la restricción de que no pueden aparecer elementos duplicados. 4 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Interface Queue Este interface está creado para utilizar las características de las colas de datos. Las colas siguen el patrón FIFO ( “First In - First Out” - “lo que entra primero, sale primero”). La característica principal de este interface es que mantiene el orden de acuerdo con el orden de inserción FIFO. 5 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L2 – Analizar la interfaz Map La interface Map es un “diccionario” de valores definidos por clave-valor. Las principales características son: • La clave debe ser única • El valor es el objeto de un tipo de nuestra colección. • A cada valor debemos acceder a través de su clave. Un Map no implementa de Collection dado que es bidimensional al incluir la estructura Clave-Valor Los principales métodos para tratar este interface Map son: • get(Object valorClave) Æ Obtiene el objeto asociado a una clave. • put(Clave clave, Valor valor) Æ Añade un par clave-valor al map • keySet() Æ Devuelve todas las claves del Map • values() Æ Devuelve todos los valores • entrySet() Æ Devuelve todos los pares clave-valor La estructura del interface Map es: 6 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Nota Un Map admite valores duplicados pero no claves duplicadas. HashMap Es el Map más sencillo y más usado. Permite asociar pares de claves y valores sin orden. No admite claves duplicadas, pero si utilizar “null” como clave. Un ejemplo en código Java de la declaración e inserción de valores es: import java.util.HashMap; public class UsoHashMap { public static void main(String argas[]){ HashMap<Integer,String> hashMap = new HashMap<Integer,String>(); hashMap.put(1,"Primer Valor"); hashMap.put(2,"Segundo Valor"); hashMap.put(null,"Valor Nulo"); } } Hemos indicado que la clave va a ser un valor de tipo Integer y que admite en la colección valores de tipo String, si intentamos introducir otro tipo de valores el compilador nos avisará del error. 7 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS HashTable Idéntico a HashMap pero no admite el valor null como clave. Un ejemplo en código Java de la declaración e inserción de valores es: import java.util.Hashtable; public class UsoHashTable { public static void main(String args[]){ Hashtable<Integer,String> hashTable = new Hashtable<Integer,String>(); hashTable.put(1,"Primer Valor"); hashTable.put(2,"Segundo Valor"); } } Si intentamos poner como clave un valor nulo lo mostrara en tiempo de ejecución, es decir, cuando el programa se esté utilizando. Este error el compilador no es capaz de detectarlo y avisarlo mientras se desarrolla. LinkedHashMap Es una clase que extiende HashMap, por lo que posee todas sus funcionalidades. Permite iterar o recorrer los elementos en el orden en el que se introdujeron debido a que utiliza una clase doblemente enlazada. Es más rápido a la hora de recorrer los datos pero más lento al insertarlos. Un ejemplo en código Java de la declaración e inserción de valores es: import java.util.LinkedHashMap; public class UsoLinkedHashMap { public static void main(String args[]){ LinkedHashMap<Integer,String> linkedHash = new LinkedHashMap<Integer,String>(); linkedHash.put(1,"Primer Valor"); linkedHash.put(2,"Segundo Valor"); } } La inserción de valores es idéntica a HashMap pero cuando queramos iterar estos valores lo hará siempre en el mismo orden que los hemos insertado. 8 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS TreeMap Es una clase que almacena en un árbol ordenado los pares Clave-Valor ordenados por los valores de las claves. Es más lenta tanto para recorrer como para insertar nuevos datos. Un ejemplo en código Java de la declaración e inserción de valores es: import java.util.TreeMap; public class UsoTreeMap { public static void main(String args[]){ TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>(); treeMap.put(2,"Segundo Valor"); treeMap.put(1,"Primer Valor"); } } En este caso a pesar del orden de inserción, al recorrerlos los devolverá ordenados por el campo clave. Nota La manera de insertar valores en las diferentes implementaciones de Map es idéntica lo que hay que pensar es que uso va a tener la colección y utilizar la correspondiente según las características que poseen. 9 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L3 – Examinar las clases colección tradicionales Todas las colecciones en Java provienen de un interface “Collection”, de este implementaban otros 3 interfaces de los cuales salen todas las clases que permiten almacenar colecciones. SET Un set es una colección que no permite duplicados. Tiene 3 clases con diferente implementación: HashSet Un hashSet posee las características principales de las colecciones Set , pero mejora la comprobación de si un objeto ya está contenido en una colección. Automáticamente al añadir un nuevo objeto a una colección se calcula el valor Hash. Este valor es un número entre -2147483647 y 2147483648 que lo almacena el propio lenguaje Java en una tabla en memoria. 10 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS A cada objeto le corresponde un único valor Hash, y dos objetos que sean iguales tendrán ese mismo valor. Así que cuando preguntamos si el objeto ya existe, no debe compararlo entero sino que comparará si el valor Hash producido ya existe. En estas colecciones el orden no se controla. LinkedHashSet Esta clase Hereda de hashSet por lo que posee todas sus características, pero añade que los objetos están doblemente enlazados y se mantiene siempre el orden de inserción. Por lo que cuando iteremos siempre se mostrarán los elementos en el mismo orden en el que se insertaron. TreeSet Cuando utilizamos una colección TreeSet, automáticamente se construye un árbol con los objetos que se van agregando al conjunto. Esto permite mantener siempre el orden aunque se añadan nuevos valores. Los objetos que añadamos deben implementar Comparable para saber qué tipo de orden queremos mantener, aunque casi todas las clases propias del lenguaje Java ya lo incoporan (String, Integer). El principal inconveniente es que debido al orden que debe mantener es menos eficiente que otras implementaciones de SET . . Un ejemplo en código Java del uso e inicialización de estas colecciones es: import java.util.HashSet; import java.util.LinkedHashSet; import java.util.TreeSet; public class UsoSet { public static void main (String args[]){ //Creación de un hashSet de Strings HashSet<String> hashSet = new HashSet<String>(); hashSet.add("Valor1"); 11 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS hashSet.add("Valor2"); hashSet.add("Valor3"); //Creación de un LinkedHashSet de Integer LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<Integer>(); linkedHashSet.add(1); linkedHashSet.add(2); linkedHashSet.add(3); //Creación de un treeSEt de Double TreeSet<Double> treeSet = new TreeSet<Double>(); treeSet.add(122.23); treeSet.add(5.23); treeSet.add(7.23); } } LIST Un List es una colección de elementos en los que se permiten duplicados y que mantiene el orden de inserción. 12 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS ArrayList Un ArrayList es una mejora del Array tradicional, ya que crece conforme se añaden elementos mientras que en un array hay que indicar desde la inicialización el tamaño. Ventajas • El tiempo de acceso a un elemento es mínimo. Inconvenientes • A la hora de eliminar es bastante lento porque una vez localizado el elemento y eliminado mueve una posición todos los elementos posteriores. Por defecto un ArrayList tiene una capacidad para 10 elementos, pero si este rango se completa lo amplia siguiendo la fórmula : (capacidad * 3) / 2 + 1 LinkedList Su funcionamiento es idéntico a ArrayList pero con la mejora todos los elementos están unidos en una serie de nodos apuntando al valor anterior y al valor siguiente. Ventajas • Eliminaciones muy rápidas ya que solo hay que indicar al elemento anterior y posterior su nueva posición. Inconvenientes • Tiene muy poco rendimiento a la hora de recorrer los datos. Vector Su funcionamiento es similar al arrayList pero los datos están sincronizados, es decir, está protegido del acceso por otros hilos. Por defecto su capacidad son 10 elementos, pero al sobrepasar este rango se duplica su capacidad lo que puede hacer que sea más lento frente a un ArrayList. Un ejemplo en código Java es: import import import import java.util.ArrayList; java.util.LinkedList; java.util.List; java.util.Vector; 13 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS public class UsoList { public static void main (String args[]){ //Creación de un arrayList de Strings List<String> lista = new ArrayList<String>(); lista.add("Valor1"); lista.add("Valor2"); lista.add("Valor3"); //Creación de un Vector de Integer List<Integer> vector = new Vector<Integer>(); vector.add(1); vector.add(2); vector.add(3); //Creación de un LinkedList de Double List<Double> linkedList = new LinkedList<Double>(); linkedList.add(122.23); linkedList.add(5.23); linkedList.add(7.23); } } Podemos observar que cuando hemos utilizado las listas en la creación del objeto hemos utilizado el interface genérico (gracias al polimorfismo): List<String> lista = new ArrayList<String>(); Esta forma de declaración es igual de válida que: ArrayList <String> lista = new ArrayList<String>(); Pero con el polimorfismo hace que el cambio de un tipo de lista sea más sencillo. 14 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS QUEUE Son conjuntos de datos FIFO (First in first out), es decir, el primer elemento en introducirse en la cola será el primero que se obtendrá al iterar la colección, y así sucesivamente. LinkedList La implementación es la propia del interface List, lo único que su característica de que mantiene los elementos enlazados con una referencia al anterior y otra al siguiente hace que para manejar conjuntos de datos FIFO sea útil. PriorityQueue Permite establecer prioridades en los elementos de una colección en funcion de una regla de comparación que se haya indicado. Se mantiene dentro de la interface Queue debido a que proporciona métodos muy útiles para mantener colas de elementos. • • • offer()Æ Añade Elementos peek()Æ Devuelve el elemento de mayor prioridad pool()ÆDevuelve el elemento de mayor prioridad y lo elimina de la colección. 15 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Un ejemplo en código Java es: import java.util.PriorityQueue; import java.util.Queue; public class UsoQueue { public static void main (String args[]){ Queue<String> listaElementos = new PriorityQueue<String>(); listaElementos.offer("Valor1"); listaElementos.offer("Valor2"); listaElementos.offer("Valor3"); } } Nota Es necesario conocer todas las ventajas e inconvenientes de las implementaciones de Collection para elegir la más adecuada (penalice menos rendimiento) a las necesidades concretas del programa. 16 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L4 – Orden con Comparable y Comparator Una de las principales características que diferencian los tipos de colecciones es si permiten ordenación. Además hay objetos que tienen predefinido unos métodos de ordenación como puede ser la clase String. En esos casos se puede invocar una característica del interface Collection denominada sort(). Un ejemplo en código Java de esta ordenación sería: import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ordenacionSimple { public static void main(String[] args) { List<String> lista = new ArrayList<String>(); lista.add("María"); lista.add("Juan"); lista.add("Pedro"); //Por defecto viene ordenada tal y como se ha insertado System.out.println("lista original:"+lista); Collections.sort(lista); //Pasa a estár ordenada alfabéticamente System.out.println("lista ordenada:"+lista); } } Nos hemos declarado una lista de String que por defecto aparecerá ordenada tal y como hemos insertado los elementos. Como la lista es de tipo String, este objeto Java por defecto implementa el interface Comparable que nos permitirá devolverla ordenada alfabéticamente si llamamos al método sort. Este método reordenará la lista en función de la implementación del interface comparable y nos devolverá la lista ordenada: ¿Y si utilizamos nuestros propios objetos? Debemos hacer exactamente lo mismo que hace el lenguaje Java para sus clases propias, implementar el interface Comparable o Comparator en función de las necesidades. 17 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Comparable Se utiliza si solo vamos a tener un único criterio de ordenación. Un ejemplo en código Java es: 1. Creamos una clase Persona e implementamos el interface Comparable, queremos que nuestra colección aparezca ordenada por apellidos. public class Persona implements Comparable<Persona> { private String nombre; private String apellidos; private int edad; public Persona(String nombre, String apellidos, int edad){ this.nombre= nombre; this.apellidos = apellidos; this.edad = edad; } @Override public int compareTo(Persona o) { return this.apellidos.compareTo(o.apellidos); } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public int getEdad() { return edad; } public void setEdad(int edad) { this.edad = edad; } } Hemos creado la persona con sus propiedades y su constructor. Hemos implementado el interface Comparable y le indicamos que es de tipo persona. Nos obliga a implementar el método compareTo que será el que utilicemos para la ordenación indicando la propiedad deseada. 18 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS 2. Una vez definido el criterio podemos utilizar el método sort y nos devolverá la lista ordenada por el criterio definido. import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UsoComparator { public static void main(String[] args) { List<Persona> lista = new ArrayList<Persona>(); lista.add(new Persona("Pedro", "Martinez",25)); lista.add(new Persona("Ana", "Lopez",12)); lista.add(new Persona("Marta", "Abidal",78)); //Por defecto viene ordenada tal y como se ha insertado System.out.println("Lista sin ordenar:"); for(int i=0;i<lista.size();i++) { System.out.println(lista.get(i).getNombre() + "- " + lista.get(i).getApellidos()); } Collections.sort(lista); System.out.println("Lista ordenada por apellido:"); //Pasa a estár ordenada alfabéticamente for(int i=0;i<lista.size();i++) { System.out.println(lista.get(i).getNombre() + "- " + lista.get(i).getApellidos()); } } } Como hemos definido el método comparteTo, al llamar a la propiedad Collections.sort devuelve la lista ordenada por el parámetro definido. 19 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Comparator Se utiliza este interface si queremos definir varios criterios de ordenación para una misma clase fuera de la definición de esta. Se deben crear tantas clases como métodos de ordenación que se deseen e implementar el interface Comparator. 1. Creamos una clase PersonasPorNombre que debe implementar de Comparator import java.util.Comparator; public class PersonasPorNombre implements Comparator<Persona> { @Override public int compare(Persona o1, Persona o2) { } } El propio compilador nos obliga a implementar el método compare que espera dos objetos del tipo que hayamos indicado en el Comparator. Dado que queremos ordenar por nombre realizamos la comparación por este campo. import java.util.Comparator; public class PersonasPorNombre implements Comparator<Persona> { @Override public int compare(Persona o1, Persona o2) { return o1.getNombre().compareTo(o2.getNombre()); } } 2. Una vez que hemos creado la clase que compara podemos utilizarla en el método sort indicándole que la ordenación debe realizarse bajo ese criterio. import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UsoComparator { public static void main(String[] args) { List<Persona> lista = new ArrayList<Persona>(); lista.add(new Persona("Pedro", "Martinez",25)); lista.add(new Persona("Ana", "Lopez",12)); lista.add(new Persona("Marta", "Abidal",78)); 20 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS //Por defecto viene ordenada tal y como se ha insertado System.out.println("Lista sin ordenar:"); for(int i=0;i<lista.size();i++) { System.out.println(lista.get(i).getNombre() + "- " + lista.get(i).getApellidos()); } Collections.sort(lista); System.out.println("Lista ordenada por apellido:"); //Pasa a estár ordenada alfabéticamente for(int i=0;i<lista.size();i++) { System.out.println(lista.get(i).getNombre() + "- " + lista.get(i).getApellidos()); } Collections.sort(lista,new PersonasPorNombre()); System.out.println("Lista ordenada por Nombre:"); //Pasa a estár ordenada alfabéticamente for(int i=0;i<lista.size();i++) { System.out.println(lista.get(i).getNombre() + "- " + lista.get(i).getApellidos()); } } } Hemos llamado al método sort indicándole la lista y la clase donde está indicado el método de ordenación. Collections.sort(nombreListaOrdenar,new ClaseComparator()); El resultado son la lista ordenada de las 3 maneras: • Por defecto Æ en el mismo orden de inserción • Apellido Æ Orden definido en la propia clase del tipo que es la lista • Nombre Æ Clase que implementa un método de ordenación propio. 21 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Nota Utilizaremos el interface Comparable para definir una ordenación por defecto en una clase, y el interface Comparator para definir otros métodos de ordenación. 22 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L5 – Utilizar colecciones genéricas Una colección en Java es un conjunto de valores que son almacenados como tipo Object. Una colección genérica es un conjunto de valores del mismo tipo y que se almacenan no como Object sino manteniendo el tipo que tenía el objeto antes de insertarse en la colección. Además garantizan que en una misma colección no haya objetos de varios tipos. Nota Las colecciones genéricas se denominan tipadas ya que están delimitadas al uso de un único tipo de objeto. Con estas colecciones se reducen los errores en tiempo de ejecución debido a colecciones con diferentes tipos de objetos. La declaración de una colección genérica es: NbClase<TipoDato> nombreVariable = new NbClase <TipoDato>(): Vamos a realizar un ejemplo en código Java que utilice colecciones genéricas y además muestre alguna de las propiedades que poseen estas colecciones. 1. Creamos la clase ColeccionesGenericas y le añadimos el método main. public class ColeccionesGenericas { public static void main(String[] args) { } } 2. Añadimos un ArrayList que solo admita datos de tipo String. import java.util.ArrayList; import java.util.List; public class ColeccionesGenericas { public static void main(String[] args) { List<String> listaGenerica = new ArrayList<String>(); } } 23 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS 3. Añadimos valores llamando al método add de la colección import java.util.ArrayList; import java.util.List; public class ColeccionesGenericas { public static void main(String[] args) { List<String> listaGenerica = new ArrayList<String>(); listaGenerica.add("Coche"); listaGenerica.add("Ciclomotor"); listaGenerica.add("Camión"); } } 4. Comprobamos que si intentamos introducir un dato de tipo entero el compilador nos muestra el error 5. Utilizamos métodos propios de Collection que nos devuelven información referente a la colección. import java.util.ArrayList; import java.util.List; public class ColeccionesGenericas { public static void main(String[] args) { List<String> listaGenerica = new ArrayList<String>(); listaGenerica.add("Coche"); listaGenerica.add("Ciclomotor"); listaGenerica.add("Camión"); System.out.println("¿La lista está vacia? " + listaGenerica.isEmpty()); System.out.println("¿Que valor hay en la posición 0? " + listaGenerica.get(0)); System.out.println("¿Que tamaño tiene la lista? " + listaGenerica.size()); } } 24 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS • • • isEmpty()Æ Método que devuelve verdadero si la lista está vacia get(0) Æ Método que devuelve el valor almacenado en la posición 0 de la lista size() Æ Método que devuelve el tamaño que tiene la lista. Recuerde Cada colección posee gran cantidad de métodos que nos ayudan a desarrollar programas, todos estos se encuentran definidos en la API online de Java. 25 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L6 – Refactorizar código no genérico existente La refactorización es una técnica que sirve para reestructurar una zona de código alterando su estructura interna pero sin modificar el comportamiento externo. Con la refactorización se gana claridad en el código y se permite un mejor entendimiento de este de cara a futuros cambios. Los propios IDEs proporcionan herramientas de refactorización, en nuestro caso que utilizamos Netbeans proporciona las siguientes herramientas de refactorización: Las herramientas más importantes de refactorización son: • Cambiar Nombre: Si queremos cambiar el nombre de una clase, también lo hace de todas sus referencias evitando errores. • Encapsular Campos: Para generar los métodos get y set de las propiedades sin tener que escribirlas. • Introducir Método: Seleccionando un conjunto de código lo convierte a un método e incluye la llamada a este para no perder funcionalidad. 26 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L7 – Escribir un programa para iterar una colección Una vez que sabemos cómo añadir elementos a una colección vamos a aprender como iterarla, para recuperar sus valores. Para iterar una colección se puede utilizar cualquiera de las estructuras de iteración que proporciona el lenguaje Java. Un ejemplo en código Java es: import java.util.ArrayList; import java.util.List; public class IteracionSimple { public static void main(String[] args) { //Inicializamos la lista List<Persona> listaPersonas= new ArrayList<Persona>(); listaPersonas.add(new Persona("Pedro", "Martinez",25)); listaPersonas.add(new Persona("Ana", "Lopez",12)); listaPersonas.add(new Persona("Marta", "Abidal",78)); listaPersonas.add(new Persona("Sonia", "Garcia",23)); //Iteramos la lista for (int i=0; i<=listaPersonas.size() -1; i++){ System.out.println("La Datos de la persona son:" + listaPersonas.get(i).getNombre() + " " + listaPersonas.get(i).getApellidos() + " " + listaPersonas.get(i).getEdad()); } } } Hemos utilizado un bucle for para recorrer la lista. Para saber el final de la iteración hemos invocado el método size() que nos devuelve el tamaño de la lista. Debemos tener especial cuidado al delimitar el inicio y el fin de la lista, ya que la primera posición es 0, y el método size nos devuelve el tamaño real (En este caso 4). Si no restásemos al método size una unidad provocaríamos un acceso ilegal en memoria intentando acceder a una posición inexistente. El resultado de la ejecución del programa será: 27 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS L8 – Examinar el bucle loop mejorado A partir de la versión 5 de java introdujeron un bucle que mejoraba el acceso a colecciones llamada For-Each Esta estructura de iteración proporciona la gran ventaja de que no hay que trabajar con índices por lo que se evitan las excepciones de acceso ilegal a memoria. Su sintaxis en código Java es: for(TipoDato nombreVariable : Coleccion){ } El mismo ejemplo que el anterior pero utilizando este nuevo bucle es: import java.util.ArrayList; import java.util.List; public class Iteracion { public static void main(String[] args) { //Inicializamos la lista List<Persona> listaPersonas= new ArrayList<Persona>(); listaPersonas.add(new Persona("Pedro", "Martinez",25)); listaPersonas.add(new Persona("Ana", "Lopez",12)); listaPersonas.add(new Persona("Marta", "Abidal",78)); listaPersonas.add(new Persona("Sonia", "Garcia",23)); //Iteramos la lista for (Persona persona: listaPersonas){ System.out.println("La Datos de la persona son:" + persona.getNombre() + " " + persona.getApellidos() + " " + persona.getEdad()); } } } En la primera parte hemos inicializado y añadido valores a la lista. Para iterarla utilizamos un bucle for each, en la en cada iteración se almacena el valor que tiene el objeto en la variable que hemos declarado interna al bucle “persona”, de esta manera se puede acceder a todos sus métodos y propiedades. El resultado de la ejecución muestra por consola los datos de la lista. 28 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS Recuerde Para iterar una colección se puede realizar mediante cualquier iterador de Java, aunque el más reciente For – Each es el que proporciona más facilidades. 29 UNIDAD DIDÁCTICA 9. – API COLLECTIONS Y GENERICS