Ordenar objetos por 2 o mas atributos
Hola ! tengo una duda aver ke como me podeis exar una mano
Tengo un arraylist de objetos con varios parametros entre ellos:
Por ejemplo una lista de 100 usuarios y quiero ordenarlos por edad,luego prioridad, por paises y luego por su ciudad y orden alfabetico,todo ello en una sola lista.
Ej:
-------------------------------------------------------------
Pepe | 22 | Alta | Albania | Tirana
-------------------------------------------------------------
Aaron | 23 | Alta | España | Cordoba
-------------------------------------------------------------
Rodri | 23 | Alta | España | Cordoba
-------------------------------------------------------------
Rodri | 23 | Alta | España | Jaen
-------------------------------------------------------------
Juan | 23 | Baja | España | Vitoria
-------------------------------------------------------------
¿Como podria hacerlo de la forma mas facil y profesional? Un saludo amigos
- Payan's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
La clase Collections tiene un
La clase Collections tiene un método sort que recibe la lista y un comparador.
En este comparador puedes especificar que cosa va antes que otra.
Puedes tener una instancia de este comparador y pasarselo a la lista cuando lo necesites.
Comparator<Usuario> comparator = new Comparator<Usuario>() {
public int compare( Usuario a, Usuario b ) {
int resultado = Integer.compare( a.edad(), b.edad());
if ( resultado != 0 ) { return resultado; }
resultado = comparaPrioridad( a.prioridad(), b.prioridad() );
if ( resultado != 0 ) { return resultado; }
resultado = a.pais().compareTo(b.pais());
if ( resultado != 0 ) { return resultado; }
resultado = a.ciudad().compareTo(b.ciudad());
if ( resultado != 0 ) { return resultado; }
resultado = a.nombre().compareTo(b.nombre());
return resultado;
}
};
...
Collections.sort( list, comparator );
Creo que ese código aún puede mejorar, ahorita no se me ocurre como, pero lo que sí tengo claro es que prefiero regresar el valor tan pronto lo tengo a tener que anidar if's
Saludos.
gracias OscarRyz ! voy
gracias OscarRyz ! voy hacerlo y os comento ok. un saludo
Me falta algo y no se como solucionarlo!Ayuda! please!
public int compare( Alumno a,Alumno b ) {
int resultado = Integer.compare( a.getEdad(), b.getEdad());
if ( resultado != 0 ) { return resultado;}
resultado = a.getNombre().compareTo(b.getNombre());
if ( resultado != 0 ) { return resultado; }
return resultado;
}
};
// no se como utilizarlo luego para que me ordene
clase Usuario
private String nombre;
private String pais;
private int edad;
public Usuario(){
this.nombre="";
this.edad=0;
this.pais="";
}
public void nUsuario(String nombre,int edad,String pais){
this.nombre=nombre;
this.edad=edad;
this.pais=pais;
}
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
public String getPais() {
return pais;
}
}
Creo una clase para almacenar los usuarios.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class almacenUsuarios {
public static ArrayList<Usuarios> vectorUsuarios=new ArrayList<Usuario>();
public void altaProducto(Alumno nuevoAlumno){
this.vectorAlumno.add(nuevoAlumno);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
/**
*
* @author Usuario
*/
public class OrdenarArrayList {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
almacenNotasAlumnos vectorProductos=new almacenNotasAlumnos();
Alumno altaProducto;
altaProducto=new Alumno();
altaProducto.nAlumno("JOSE",23,"ESPAÑA");
vectorProductos.altaProducto(altaProducto);
altaProducto=null;
altaProducto=new Alumno();
altaProducto.nAlumno("Aaron",22,"ESPAÑA");
vectorProductos.altaProducto(altaProducto);
altaProducto=null;
altaProducto=new Alumno();
altaProducto.nAlumno("JOSE",23,"ESPAÑA");
vectorProductos.altaProducto(altaProducto);
altaProducto=null;
Collections.sort( almacenNotasAlumnos.vectorAlumno, new OrdenaCod());
for(int x=0;x<almacenNotasAlumnos.vectorAlumno.size();x++){
System.out.println("Nombre: "+ almacenNotasAlumnos.vectorAlumno.get(x).getNombre()+
" Edad: "+ almacenNotasAlumnos.vectorAlumno.get(x).getEdad()+
" Pais: "+ almacenNotasAlumnos.vectorAlumno.get(x).getPais());
}
}
class OrdenaCod implements Comparator{
public int compare(Object o1, Object o2) {
Alumno otroproducto= (Alumno)o1;
Alumno otroproducto2=(Alumno)o2;
return otroproducto.getEdad.compareTo(otroproducto2.getEdad);
}}}
//
Lo he ordenado en este caso solo por un atributo ,en este caso por edad,pero sigue sin salirme ... el ordenarlo luego por nombre u pais.
Lo he hecho algo mas simple y he eliminado el metodo comparaPrioridad.
ya luego cuando lo entienda ,lo agrego,pero de momento no lo entiendo muxo,ya he conseguido ordenar por un atributo,pero sigo sin sacar por dos, el metodo que me pasaste de compareTO no se como utilizarlo para llamarlo en el collection.sort porque ahi me devuelve resultado que es un int y el metodo que yo tengo me devuelve el objeto
¿como utilizo el resultado para ordenar luego los objetos?
un saludo.
Te paso la clase leer para que puedas probarlo si lo deseas
public class leer {
//--------------------------------------------- Recoje un dato tipo String.
public static String dato() {
String sdato="";
try{
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader FlujoE=new BufferedReader(isr);
sdato=FlujoE.readLine();
}
catch (IOException e){
System.err.println("Error: "+ e.getMessage());
}
return sdato;
}
//------------------------------------Recoje un dato de tipo Int.
public static int entero(){
boolean sw=true;
int x=0;
while(sw){
try{
x=Integer.parseInt(dato());
sw=false;
}
catch (Exception ex){
System.out.println("ERROR: Vuelva a introducir el dato.");
}
}
return x;
}
public static int enteroProducto(){
boolean sw=true;
int x=0;
while(sw){
try{
x=Integer.parseInt(dato());
if(x>=1&&x<=20)
sw=false;
else
System.out.println("El numero no es correcto, (Del 1 al 20).");
}
catch (Exception ex){
System.out.println("ERROR: Vuelva a introducir el dato.");
}
}
return x;
}
public static int enteroMinimo(){
boolean sw=true;
int x=0;
while(sw){
try{
x=Integer.parseInt(dato());
if(x>0)
sw=false;
else
System.out.println("El numero no es correcto, (Del 1 al 20).");
}
catch (Exception ex){
System.out.println("ERROR: Vuelva a introducir el dato.");
}
}
return x;
}
public static double doublePrecio(){
boolean sw=true;
double x=0;
while(sw){
try{
x=Double.parseDouble(leer.dato());
if(x>0)
sw=false;
else
System.out.println("Precio no es correcto.");
}
catch (Exception ex){
System.out.println("ERROR: Vuelva a introducir el dato.");
}
}
return x;
}
//-------------------------------------- Recoje un dato tipo dooble.
public static double decimal(){
boolean sw=true;
double x=0;
while(sw){
try{
x=Double.parseDouble(dato());
sw=false;
}
catch (Exception ex){
System.out.println("ERROR: Vuelva a introducir el dato.");
}
}
return x;
}
//--------------------------------------- Recoje cualquier caracter tipo char
public static char unCaracter(){
boolean sw=true;
int tamaño;
char x=' ';
String charDato;
while (sw){
try{
charDato=dato();
tamaño=charDato.length();
if(tamaño>1)
throw new error ("Tamaño excedido.");
x=charDato.charAt(0);
sw=false;
}
catch(error ex){
System.out.println(ex.getMessage());
}
}
return x;
}
//------------------------------------------Recoje un char pero solo letra.
public static char CharLetra(){
boolean sw=true;
boolean esLetra=false;
char x=' ';
while (sw){
try{
x=unCaracter();
esLetra=Character.isLetter(x);
if(esLetra==false)
throw new error("No es una letra");
sw=false;
}
catch(error ex){
System.out.println(ex.getMessage());
}
}
return x;
}
//-----------------------------------------Recoje un char pero solo numero.
public static char charNum(){
boolean sw=true;
boolean esLetra=false;
char x=' ';
while (sw){
try{
x=unCaracter();
esLetra=Character.isDigit(x);
if(esLetra==false)
throw new error("No es un número");
sw=false;
}
catch(error ex){
System.out.println(ex.getMessage());
}
}
return x;
}
}//llave de fin de la clase leer
class error extends Exception{
error (String msg){
super (msg);
}
}
Espero que me aclareis como realizarlo o si lo he planteado mal y lo debo hacer de otra forma.Un saludo.
Comparar prioridad es otro
Comparar prioridad es otro método. Crealo y que te devuelva 0 si tienen la misma prioridad -1 si uno tiene más que otroa o 1 si tienen menos que otra (
Algo como:
if a == "Alta" and "B" == "Baja" return -1
if b ="Baja" and ... blabalabl return 1
etc.
etc
Revisa la firma de Collections.sort, no recibe un arraylist, sino una lista (creo) Intenta con:
List<Usuario> a = new ArrayList<Usuario>();
en última instancia lee el mensaje de error y trata de entender que te está diciendo el compilador.Además lo que tienes que poner el la lista que quieres ordenar ( el vector de usuarios )
gracias me pongo a ello.haber
gracias me pongo a ello.haber ke tal me sale. un saludoo
He corregido el codigo ,te he
He corregido el codigo ,te he pasado el codigo entero.
Logro ordenar el arraylist de objetos por cualquiera de los parametros.pero solo uno.no dos ni mas.
He intendo luego guardar ese arraylist de objetos en otro arraylist de objetos y luego ordenarlo por otro
parametro pero no respeta como estaba ordenado anteriormente como es logico..
el metodo que devuelve
el resultado.,que es este:
public int compare( Alumno a,Alumno b ) {
int resultado = Integer.compare( a.getEdad(), b.getEdad());
if ( resultado != 0 ) { return resultado;}
resultado = a.getNombre().compareTo(b.getNombre());
if ( resultado != 0 ) { return resultado; }
return resultado;
}
};
" no se como utilizarlo....para luego ordenar el arraylist de objetos segun ese metodo ".
Mmhh pues no te entendí muy
Mmhh pues no te entendí muy bien, pero acá esta un ejemplo de como si funciona ordenando por varios criterios
Por ejemplo, cuando el nombre, la edad, y el pais son el mismo, se toma en consideración la ciudad.
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
class OrdenarPor {
public static void main( String ... args ) {
List<Persona> personas = new ArrayList<>(Arrays.asList(
new Persona("Oscar", 34, "Alta", "Mexico", "Zacatecas"),
new Persona("Oscar", 34, "Alta", "Mexico", "Mexico"),
new Persona("Aaron", 23, "Alta", "España", "Cordoba"),
new Persona("Pepe", 22, "Alta", "Albania", "Tirana"),
new Persona("Rodri", 23, "Alta", "España", "Cordoba"),
new Persona("Juan", 23, "Baja", "España", "Vitoria"),
new Persona("Rodri", 23, "Alta", "España", "Jaen")
));
Comparator<Persona> comparador = new Comparator<Persona>() {
public int compare( Persona a, Persona b ) {
int resultado = Integer.compare( a.edad(), b.edad());
if ( resultado != 0 ) { return resultado; }
//resultado = comparaPrioridad( a.prioridad(), b.prioridad() );
//if ( resultado != 0 ) { return resultado; }
resultado = a.pais().compareTo(b.pais());
if ( resultado != 0 ) { return resultado; }
resultado = a.ciudad().compareTo(b.ciudad());
if ( resultado != 0 ) { return resultado; }
resultado = a.nombre().compareTo(b.nombre());
return resultado;
}
};
System.out.printf( "Antes: %s%n", personas );
Collections.sort(personas, comparador );
System.out.printf( "Despues: %s%n", personas );
}
}
class Persona {
private String nombre;
private int edad;
private String prioridad;
private String pais;
private String ciudad;
public Persona(String nombre, int edad, String prioridad, String pais, String ciudad ) {
this.nombre = nombre;
this.edad = edad;
this.prioridad = prioridad;
this.pais = pais;
this.ciudad = ciudad;
}
public String toString() {
return String.format("%s (%d). %s. Ubicación: %s, %s%n", nombre, edad, prioridad, ciudad, pais);
}
// en realidad deberían ser : getEdad(), getNombre() etc.
public int edad() { return edad; }
public String nombre() { return nombre; }
public String pais() { return pais; }
public String ciudad() { return ciudad; }
}
Salida:
Antes: [Oscar (34). Alta. Ubicación: Zacatecas, Mexico
, Oscar (34). Alta. Ubicación: Mexico, Mexico
, Aaron (23). Alta. Ubicación: Cordoba, España
, Pepe (22). Alta. Ubicación: Tirana, Albania
, Rodri (23). Alta. Ubicación: Cordoba, España
, Juan (23). Baja. Ubicación: Vitoria, España
, Rodri (23). Alta. Ubicación: Jaen, España
]
Despues: [Pepe (22). Alta. Ubicación: Tirana, Albania
, Aaron (23). Alta. Ubicación: Cordoba, España
, Rodri (23). Alta. Ubicación: Cordoba, España
, Rodri (23). Alta. Ubicación: Jaen, España
, Juan (23). Baja. Ubicación: Vitoria, España
, Oscar (34). Alta. Ubicación: Mexico, Mexico
, Oscar (34). Alta. Ubicación: Zacatecas, Mexico
]
Si quisieras ordenar primero por ciudad, tendrías que ponerlo (en otro comparador) al principio:
if a.ciudad().compareTo( b.ciudad() ) {
.... etc. etc
...
Ya no leí el reste de tu código sobre como capturas los datos porque creo que no viene mucho al caso. Haz que funcione primero con datos fijos (como en mi ejemplo) y cuando hayas dominado esa parte puedes seguir con otras.
Espero que esto te ayude.
Muchas gracias por ayudarme
Muchas gracias por ayudarme con esto y aplicar tu tiempo a resolverme estas dudas,me pongo con ello ahora mismo
un saludo amigo!