Download ARRAYLISTS (119661)
Document related concepts
no text concepts found
Transcript
Las bases de ArrayList La clase java.util.ArrayList es una de las mas usadas de todas las colecciones de Framework. Es como un array con vitaminas. Algunas de las ventajas de ArrayList son: Crece dinamicamente Provee de inserciones mas poderosas y mejores mecanismos de busqueda que los arrays. Echemos un vistazo al uso de ArrayList conteniendo cadenas. Una clave del diseño de las colecciones del Framework es que proveen de una rica funcionalidad al nivel de las principales interfaces: List, Set y Map. En la practica, normalmente querras instanciar un ArrayList de forma poliformica: List myList = new ArrayList(); Escrito en Java 5 seria: List<String> myList = new ArrayList<String>(); Esta clase de declaracion sigue el principio de "codigo a interface", y crea el uso de genericos. Hablaremos bastante del uso de genericos en este capitulo, pero por ahora, solo hay que saber que al igual que en Java 5, la sintaxis <String> es la manera de declarar el tipo de coleccion. Antes de Java 5, no habia manera de especificar el tipo de una coleccion, y cuando cubramos los genericos, hablaremos de la implicacion al mezclar Java 5 (tipificado) con las versiones anteriores a Java 5 (sin tipificar) en las colecciones. En muchas maneras, ArrayList<String> es muy similar a String[], declara un contenedor que solo puede almacenar cadenas, pero es mas poderoso que un String[]. Echemos un vistazo a algunas de las capacidades que un ArrayList tiene: ? 1 2 import java.util.*; 3 public class TestArrayList { public static void main(String[] args) { 4 List<string> test = new ArrayList<string>(); 5 String s = "hi"; 6 test.add("string"); 7 test.add(s); test.add(s+s); 8 System.out.println(test.size()); 9 System.out.println(test.contains(42)); 10 System.out.println(test.contains("hihi")); 11 test.remove("hi"); 12 System.out.println(test.size()); 13} } 14</string></string> 15 lo que produce: 3 false true 2 Hay un moton de movimiento en este pequeño programa. Fijate que cuando declaramos el ArrayList no le dimos un tamaño. Luego le preguntamos por su tamaño, le pudimos preguntar si tenia contenido especifico, tambien le borramos el objeto de enmedio, y le volvimos a preguntar su tamaño. Autoboxing con colecciones En general, las colecciones almecenan objetos, pero no primitvos. Antes de Java 5, era muy comun el uso de clases de envoltorio para proveer a las clases de una manera de meter un primitivo en una coleccion. Antes de Java 5, tenias que envolver el primitivo a mano y despues podias meterlo en la coleccion. Con Java 5, los primitivos todavia estan envueltos, pero el autoboxing lo hace por ti. List myInts = new ArrayList(); // pre Java 5 declaration myInts.add(new Integer(42)); // had to wrap an int En Java 5, podemos hacer: myInts.add(42); // autoboxing! En este ejemplo, hemos puesto un objeto Integer a myInts (no un primitivo int), solo que el autoboxing envolvio el primitivo por nosotros. Clasificando las colecciones y los arrays Ordenar y buscar topicos ha sido añadido al examen de Java 5. Las colecciones y los arrays pueden ser ordenados y hacer busquedas usando metodos del API. Ordenando colecciones Comencemos por algo simple como ordenar un ArrayList de cadenas alfabeticamente. Podria ser mas facil? Bien, esperaremos un rato mientras vas y buscas el metodo sort() de ArrayList. Lo tienes? Naturalmente, ArrayList no te da ninguna forma de ordenar su contenido, pero java.util.Collection si: ? 1 import java.util.*; class TestSort1 { 2 public static void main(String[] args) { 3 ArrayList<string> stuff = new ArrayList<string>(); // #1 stuff.add("Denver"); 4 stuff.add("Boulder"); 5 stuff.add("Vail"); 6 stuff.add("Aspen"); 7 stuff.add("Telluride"); System.out.println("unsorted " + stuff); 8 Collections.sort(stuff); // #2 9 System.out.println("sorted " + stuff); 10 } 11} 12</string></string> 13 14 15 lo que da: unsorted [Denver, Boulder, Vail, Aspen, Telluride] sorted [Aspen, Boulder, Denver, Telluride, Vail] En la linea #1 se declara un ArrayList de cadena, y en la linea #2 se ordena el ArrayList alfabeticamente. Hablaremos mas sobre la clase Collection a lo largo de la clase Array en otra seccion, por ahora nos ocuparemos de ordenar cosas. Imaginemos que estamos construyendo una aplicacion de un automatismo para una casa. Hoy estamos centrados en el home cinema, y mas especificamente, en el control del DVD. Ya tenemos el I/O Software para leer y escribir datos entre el dvdInfo.txt y las instancias de la clase DVDInfo. Aqui esta la clave del aspecto de la clase: ? 1 2 class DVDInfo { String title; 3 String genre; 4 String leadActor; 5 DVDInfo(String t, String g, String a) { 6 title = t; genre = g; leadActor = a; } 7 public String toString() { 8 return title + " " + genre + " " + leadActor + "\n"; 9 } 10 // getters y setter van aqui 11} 12 Aqui estan los datos de dvdinfo.txt: Donnie Darko/sci-fi/Gyllenhall, Jake Raiders of the Lost Ark/action/Ford, Harrison 2001/sci-fi/?? Caddy Shack/comedy/Murray, Bill Star Wars/sci-fi/Ford, Harrison Lost in Translation/comedy/Murray, Bill Patriot Games/action/Ford, Harrison En nuestra aplicacion, queremos crear una instancia de DVDInfo para cada linea de datos que leemos del fichero dvdinfo.txt. Por ejemplo, queremos parsear la linea datos (te acuerdas de String.split()?) y llenar las tres instancias de DVDInfo. Finalmente, queremos poner todas las intancias de DVDInfo en un ArrayList. Imagina que el metodo populateList() hace todo esto. Aqui hay una pequeña pieza de codigo de nuestra aplicacion: ArrayList dvdList = new ArrayList(); populateList(); // adds the file data to the ArrayList System.out.println(dvdList); Puedes obtener algo como esto: [Donnie Darko sci-fi Gyllenhall, Jake , Raiders of the Lost Ark action Ford, Harrison , 2001 sci-fi ?? , Caddy Shack comedy Murray, Bill , Star Wars sci-fi Ford, Harrison , Lost in Translation comedy Murray, Bill , Patriot Games action Ford, Harrison ] Nota: Hemos sobrescrito el metodo de DVDInfo.toString(), asi que cuando hemos invocado println() en el ArrayList, se invoca toString() para cada instancia. Ahora que tenemos ArrayList populado, ordenemoslo: Collections.sort(dvdlist); Oppps! ahora hemos obtenido esto: TestDVD.java:13: cannot find symbol symbol : method sort(java.util.ArrayList) location: class java.util.Collections Collections.sort(dvdlist); Que ha pasado aqui? Sabemos que la clase Collection tiene el metodo sort(), este error hace pensar que Collection no tiene un metodo sort() que pueda tomar un dvdlist. Lo que significa que debe haber algo equivocado en el argumento que le hemos pasado (dvdinfo). Si ya te lo has imaginado, adivinamos que lo hiciste sin la ayuda del error mostrado arriba... Como demonios ordenas las instancias de DVDInfo? Por que pueden ordenarse las cadenas? Cuando miras el API de Collection.sort(), la primera reaccion puede ser panico. Tranquilo, nuevamente los genericos te ayudaran con este metodo que parece estar enloquecido. Si has leido la descripcion del metodo sort() con un argumento, veras que sort() toma como argumento una List, y que el objeto List debe implementar una interfaz llamada Comparable. Esto nos dice que String implementa Comparable, y esa es la razon de por que pudimos ordenar una lista de cadenas usando el metodo Collection.sort(). La interfaz Comparable La interfaz Comparable se usa en las colecciones con el metodo Collection.sort() y java.utils.Array.sort() para ordenar listas y arrays de objetos respectivamente. Para implementar Comparable, una clase debe implementar un solo metodo, compareTo(). Un ejemplo de invocacion de compareTo(): int x = thisObject.compareTo(anotherObject); El metodo compareTo() devuelve un int con las siguientes caracteristicas: negativo Si esteObjeto < otroObjeto zero Si esteObjeto == otroObjeto positivo Si esteObjeto > otroObjeto El metodo usa compareTo() para determinar como la lista o el objeto array debe ser ordenado. Al implementar compareTo() en tus clases, puedes usar cualquier criterio que se te ocurra para ordenar las instancias de tu clase. Volviendo al ejemplo de DVDInfo, nosotros vamos a coger la manera facil y vamos a usar la implementacion de compareTo() de la clase String: ? 1class DVDInfo implements Comparable<dvdinfo> { // #1 2 // existing code 3 public int compareTo(DVDInfo d) { return title.compareTo(d.getTitle()); // #2 4 } } 5 </dvdinfo> 6 En la linea #1 declaramos que DVDInfo implementa Comparable, de esta manera los objetos DVDInfo podran ser comparados con otros objetos DVDInfo. En la linea #2 implementamos compareTo() para comparar los dos objetos titulo del objeto DVDInfo. Ya que sabemos que los titulos son cadenas, y que las cadenas implementan Comparable, esta es una manera sncilla de ordenar los objetos DVDInfo, por el titulo. Antes de que vinieran los genericos en Java 5, tendriamos que haber implementado Comparable de esta manera: ? 1 class DVDInfo implements Comparable { 2 // existing code 3 public int compareTo(Object o) { // toma un objeto en lugar // de un tipo especifico 4 DVDInfo d = (DVDInfo)o; 5 6} } return title.compareTo(d.getTitle()); 7 Esto es todavia legal, pero puedes ver que es una manera dolorosa y arriesgada, ya que tienes que hacer un casteo, y necesitas verificar que el casteo no va a fallar antes de que sea ejecutado. Examen Atencion, Es importante recordar que cuando sobrescribes equals(), tienes que tomar por argumento el tipo Object, pero cuando sobrescribes compareTo() tienes que tomar como argumento el tipo que estas ordenando. Poniendolo todo junto, nuestra clase DVDInfo quedaria asi: ? DVDInfo implements Comparable<dvdinfo> { 1 classString title; 2 String genre; String leadActor; 3 DVDInfo(String t, String g, String a) { 4 title = t; genre = g; leadActor = a; 5 } 6 public String toString() { return title + " " + genre + " " + leadActor + "\n"; 7 } 8 public int compareTo(DVDInfo d) { 9 return title.compareTo(d.getTitle()); 10 } 11 public String getTitle() { return title; 12 } 13 // other getters and setters 14} 15</dvdinfo> 16 17 18 19 Ahora cuando invocamos Collections.sort(dvdlist); obtenemos: [2001 sci-fi ?? , Caddy Shack comedy Murray, Bill , Donnie Darko sci-fi Gyllenhall, Jake , Lost in Translation comedy Murray, Bill , Patriot Games action Ford, Harrison , Raiders of the Lost Ark action Ford, Harrison , Star Wars sci-fi Ford, Harrison ] Yeehaaa! Nuestro ArrayList ha ordenado esto por titulo. Naturalmente, si queremos que nuestra automatizacion sea lo mas, probablemente querremos ordenar las colecciones de DVD de diferenctes formas. Al implementar el metodo compareTo() pudimos ordenar. Lo hicimos en una clase, pero como hacemos para que nuestras clases se ordenen de una manera especifica a compareTo()? Buena pregunta. Afortunadamente, la respuesta viene ahora. Ordenando usando Comparator Mientras estabas mirando el metodo Collections.sort() podrias haberte dado cuenta de que es una version sobrecargada de sort() que toma un List, y algo llamado Comparator. La interfaz Comparator te da la capacidad de ordenar una coleccion de un millar de maneras distintas. La otra cosa que hace la interfaz Comparator es que te permite ordenar las instancias de cualquier clase, incluso las clases que no puedes modificar, al contrario que Comparable, que te obliga a cambiar las instancias de las clases que quieres ordenar. La interface Comparator es tambien muy facil de implementar, tiene solo un metodo, compare(). Aqui hay una pequeña clase que puede ser usada para ordenar una List de instancias de DVDInfo, por genero. ? 1import java.util.*; 2class GenreSort implements Comparator<dvdinfo> { public int compare(DVDInfo one, DVDInfo two) { 3 return one.getGenre().compareTo(two.getGenre()); 4 } 5}</dvdinfo> 6 El metodo Comparator.compare() devuelve un int cuyo valor de retorno es el mismo que el de Comparable.compareTo(). En este caso estamos cogiendo ventaja al pedirle a compareTo() que haga el trabajo de comparacion por nosotros. Aqui hay un programa que nos permite testear ambos codigos Comparable y nuestro nuevo codigo Comparator: ? 1 2 3 import java.util.*; 4 import java.io.*; // populateList() needs this public class TestDVD { 5 ArrayList<dvdinfo> dvdlist = new ArrayList<dvdinfo>(); 6 public static void main(String[] args) { new TestDVD().go(); 7 } 8 public void go() { 9 populateList(); 10 System.out.println(dvdlist); // output as read from file 11 Collections.sort(dvdlist); System.out.println(dvdlist); // output sorted by title 12 GenreSort gs = new GenreSort(); 13 Collections.sort(dvdlist, gs); 14 System.out.println(dvdlist); // output sorted by genre 15 } public void populateList() { 16 // read the file, create DVDInfo instances, and 17 // populate the ArrayList dvdlist with these instances 18 } 19} 20</dvdinfo></dvdinfo> 21 22 Ya habias visto las dos primeras salidas, esta es la tercera: [Patriot Games action Ford, Harrison , Raiders of the Lost Ark action Ford, Harrison , Caddy Shack comedy Murray, Bill , Lost in Translation comedy Murray, Bill , 2001 sci-fi ?? , Donnie Darko sci-fi Gyllenhall, Jake , Star Wars sci-fi Ford, Harrison ] Ya que Comparable y Comparator son similares, intentaran confundirte en el examen. Por ejemplo, se te puede preguntar que implementes el metodo compareTo() en la interface Comparator. Memoriza la siguiente tabla para conocer las diferencias entre estas dos interfaces: java.lang.Comparable int objOne.compareTo(objTwo) java.util.Comparator int compare (objOne, objTwo) Devuelve negativo si obj1 < obj2 cero si obj1 == obj2 positivo si obj1 > obj2 Debes modificar la clase de las instancias que quieras ordenar. Solo se puede crear una unica secuencia de orden. Se implementa frecuentemente en los API de: String, clases de envoltorio, Date, Calendar... Igual que Comparable Debes construir una clase separada de las clases cuyas instancias quieres ordenar. Se pueden crear tantas secuencias como se quiera. Pretende ser aplicado para clasificar las clases de terceros. Para acabar con este apartado, voy a mostrar un codigo creado a partir de lo visto hasta aqui. Se trata de una agenda con nombres y numeros donde se exponen tres maneras de ordenar la agenda. La primera manera, es la natural, el orden creado por indexacion. La segunda manera, es el orden creado por el orden alfabetico de los nombres. La tercera manera, es el orden creado por los numeros, que por supuesto, son ficticios, pero sirven para la demostracion. Aqui el codigo: ? 1 import java.text.NumberFormat; 2 import java.util.ArrayList; 3 import java.util.Collections; 4 import java.util.Comparator; 5 public class Main { 6 7 public static void main(String [] args) 8 { ArrayList l = new ArrayList(); 9 l.add(new Agenda("Pepe",112233)); 10 l.add(new Agenda("Juan",908978)); 11 l.add(new Agenda("Vicente",645720)); 12 l.add(new Agenda("Bartolo",6543599)); 13 14 // Impresion orden insercion System.out.println("Orden natural: " + l); 15 16 // Impresion orden alfabetico 17 Collections.sort(l); 18 System.out.println("Orden alfabetico: " + l); 19 20 // Impresion por numero inventado 21 AgendaPorNumeros apn = new AgendaPorNumeros(); Collections.sort(l, apn); 22 System.out.println("Ordenado por numeros: " + l); 23 24 25 } 26 } 27 28 class Agenda implements Comparable 29{ 30 String nombre; 31 Integer numero; // Envoltorio, porque solo podemos usar objetos en 32 // la comparacion. 33 34 Agenda (String nombre, Integer numero) 35 { 36 this.nombre = nombre; this.numero = numero; 37 } 38 39 String getNombre() { return this.nombre; } 40 Integer getNumero() { return this.numero; } 41 42 public String toString() 43 { String numero = 44 45NumberFormat.getInstance().format((int)this.numero); return this.nombre + " " + numero; // Sobrescribiendo metodo 46 } 47 48 @Override 49 public int compareTo(Object a) { // Objeto! no un tipo! 50 Agenda ag = (Agenda)a; 51 return this.nombre.compareTo(ag.getNombre()); 52 } 53} 54 55class AgendaPorNumeros implements Comparator<agenda> 56{ 57 @Override 58 public int compare(Agenda a1, Agenda a2) { 59 return a1.getNumero().compareTo(a2.getNumero()); 60 } 61 62}</agenda> 63 64 65 66 67 68 y aqui el resultado obtenido: Orden natural: [Pepe 112.233, Juan 908.978, Vicente 645.720, Bartolo 6.543.599] Orden alfabetico: [Bartolo 6.543.599, Juan 908.978, Pepe 112.233, Vicente 645.720] Ordenado por numeros: [Pepe 112.233, Vicente 645.720, Juan 908.978, Bartolo 6.543.599] Te acuerdas de format()? lo he usado para añadir el punto a los numeros, de esta manera se puede ver mejor su valor. Buenas noches compañeros, tengo un problema curioso...y es que, aunque en su momento aprendí que para recorrer un array era: array.lenght ; en mi netbeans, no me da la opción de ponerlo, solo me deja poner array.size(); ¿Alguna razón o como entonces puedo obtener la ultima posición del un array? Actualmente tengo esto: for (int i=0;i<GrupoUsuarios.size();i++){ int id=(GrupoUsuarios.lastIndexOf(i)); } ¿No se supone que con poner array.lenght()-1 o algo asi, era para obtener la ultima dirección del array? Un saludo y gracias si lo que quieres es recorrer un arraylist hazle un for each for(tipoArrayList nombrevarialbe: ArrayList){ code } ejemplo: Arraylist<String> nombres = new ArrayList<>(); //cargamos cosas en este array y lo recorremos asi: for(String n: nombres){ System.out.println(n); } creo que se ve claro si no es asi dilo y intento explicaretelo de otro modo o con mas ejemplos ArrayList + Objetos Java Buenas, maestros de CHW. Vengo a molestar con una pregunta que quizá puede ser bien simple, pero en donde me enrrede de pura pava, supongo. Les cuento... Tengo que hacer una interfaz gráfica que ingrese alumnos y sus notas a un AL y que luego las muestre en un cuadro de texto (¿Háganme la tarea ? xDD no, no.. mentira xD) Entre tanto PHP, Java quedó re-abandonado, y me perdí profundamente en sus garras Parti por hacer la interfaz gráfica con un JFrame, he hice una clase llamada alumno con sus atributos, etc... Declaré el ArrayList como atributo, e hice 2 métodos: uno para ingresar el alumno y otro para "mostrarlo", sólo.. que para hacerlo más óptimo, me tiré a que el AL (ArrayList) guardara objetos... y el problema es que el método para mostrar los datos del AL no está funcionando. Les muestro lo que hice: Código: // Método de ingreso de alumnos a ArrayList de objetos public void ingresa_alumno(Alumnos dato) { // Ingreso del objeto al ArrayList ingreso.add(dato); } El parámetro dato es un objeto de tipo Alumno y que se pasa como parámetro desde la interfaz Código: Alumnos obj_ingreso = new Alumnos(txt_idAlumno.getText(),txt_nombre.getText(),txt_apellido.getTe xt(), nota1,nota2,nota3,nota4,notaFinal,situacion); Alumnos auxiliar = new Alumnos(); auxiliar.ingresa_alumno(obj_ingreso); El método para obtener los datos es el siguiente... Código: // Metodo de obtencion de datos public void obtiene_datos() { for(Alumnos tmpObjeto : ingreso){ System.out.println("Nombre del alumno: " + tmpObjeto.getNombre()); } } Y lo llamo desde la interfaz así... Código: Alumnos obj = new Alumnos(); obj.obtiene_datos(); NOTA: Hay puros system.out.println porque lo estaba probando. El asunto es que el método obtener datos no me funciona... sin embargo, si coloco el ciclo for en el método de ingreso.. (onda que lo muestre al ingresar), si lo muestra... Como esto... Código: // Método de ingreso de alumnos a ArrayList de objetos public void ingresa_alumno(Alumnos dato) { // Ingreso del objeto al AL ingreso.add(dato); for(Alumnos tmpObjeto : ingreso){ System.out.println("Nombre del alumno: " + tmpObjeto.getNombre()); } } Y no se me ocurre dónde me puedo estar cayendo... Si me pudieran dar una mano, o decirme de qué manera resolverlo... (ya supongo qe debe ser un error medio tonto) se los agradecería. Gracias, gente. Saludos. Citar 17/03/2011 #2 oniwabanshu Pajarito Nuevo Fecha de ingreso 25 Nov, 10 Mensajes 59 Re: ArrayList + Objetos Java Quizas estas creando dos veces el objeto alumnos, una para agregar los datos y la otra cuando quieres imprimir el resultado. prueba con el siguiente codigo. Lista.java Código: import java.util.ArrayList; import java.util.List; public class Lista { private List<Obj> lista = new ArrayList<Obj>(); public void add(Obj o){ lista.add(o); } public void show(){ for(Obj o:lista){ System.out.println(o.getS()); } } } Obj.java Código: public class Obj { private String s; public String getS() { return s; } public void setS(String s) { this.s = s; } } Main.java Código: public class Main { public static void main(String[] args) { Lista lista = new Lista(); Obj o1 = new Obj(); Obj o2 = new Obj(); o1.setS("dato1"); o2.setS("dato2"); lista.add(o1); lista.add(o2); lista.show(); } } Citar 17/03/2011 #3 edith_venegas Ñoña en evolución :B ! Fecha de ingreso 28 Nov, 08 Ubicación Santiago, Santiago Centro Mensajes 176 Re: ArrayList + Objetos Java ¡Eres grande! Te lo agradezco, de veras. El código que me pusiste era casi similar al código con el cual había empezado a hacer el ejercicio... aunque la parte que me hizo chispa fue el de crear 2 veces el objeto Alumnos... efectivamente, esa era la razón. En esta parte Código: Alumnos obj = new Alumnos(); obj.obtiene_datos(); Estaba declarando el objeto de nuevo, y en blanco... era obvio que no imprimiría nada. Así que definí un objeto de la clase alumno en los atributos de la clase interfaz (la que contenía el JFrame) y con esa me las arreglé para llamar a todos los métodos void. Gracias por tu ayuda, te has pasado, en serio