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