Java - Ordenar arraylist

 
Vista:

Ordenar arraylist

Publicado por Ana (35 intervenciones) el 30/11/2021 18:08:12
hola buenas tardes. Necesito ordenar un arraylist de mayor a menor
Tengo un arraylist con dos atributos, nombre y edad, y necesito ordenarlo por el atributo edad.

tengo entendido que se utiliza el medoto sort() pero nose como utilizarlo

muchas gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ordenar arraylist

Publicado por Kabuto (1383 intervenciones) el 01/12/2021 00:18:59
Hola Ana.
Hay dos formas:
- Implementando la interfaz Comparable a la clase que quieres ordenar, para que esta sepa decirle al ArrayList como se han de ordenar cuando se invoque el método sort().
- Creando un objeto Comparator para pasárselo como parámetro al método sort() y será este objeto quien le diga cuáles son las reglas de comparación.

Normalmente, la más interesante es la primera forma, que sea la propia clase quien sepa indicar como se comparan sus objetos.

Supongamos esta clase Persona, implementa la interfaz Comparable la cuál nos obliga a sobreescribir el método compareTo(), que es donde indicaremos las reglas de comparación.
En este caso, estamos ordenando por edad, de menor a mayor.
El método lo que hace es recibir "otro" objeto Persona con el que comparar edades.
Si "este" objeto Persona tiene edad menor que el "otro", entonces ha de devolver un valor negativo, por ejemplo -1
Si por el contrario, "este" objeto Persona tiene mayor edad que el "otro", entonces se devuelve un valor positivo.
Si la edad es la misma, entonces se devuelve 0


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Persona implements Comparable<Persona> {
 
	private String nombre;
	private int edad;
 
	public Persona(String nombre, int edad) {
		this.nombre = nombre;
		this.edad = edad;
	}
 
	@Override
	public int compareTo(Persona otraPersona) {
 
		if (this.edad < otraPersona.edad)
			return -1;
		else if (this.edad > otraPersona.edad)
			return 1;
		else
			return 0; //Tienen la misma edad
	}
 
	@Override
	public String toString() {
		return String.format("Nombre: %s -- Edad: %d", nombre, edad);
	}
 
}

Con estas reglas, luego el ArrayList ya es capaz de ordenar los objetos Persona cuando se lo pidamos. Para ello invocamos el método sort(), quien como dije antes, espera recibir un objeto Comparator, pero si en lugar de eso le pasamos valor null, entonces aplicará la reglas de ordenación de la interfaz Comparable que implementan los objetos Persona, que es precisamente lo que nos interesa.

Si probamos este código:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.ArrayList;
 
public class OrdenarPorEdad {
 
	public static void main(String[] args) {
 
		var listaPersonas = new ArrayList<Persona>();
		listaPersonas.add(new Persona("Juan", 45));
		listaPersonas.add(new Persona("Sara", 38));
		listaPersonas.add(new Persona("Carmen", 49));
		listaPersonas.add(new Persona("David", 22));
		listaPersonas.add(new Persona("Luis", 58));
		listaPersonas.add(new Persona("Laura", 33));
		listaPersonas.add(new Persona("Fermin", 46));
		listaPersonas.add(new Persona("Soledad", 33));
 
		System.out.println("Lista personas SIN ordenar:");
		for (Persona p: listaPersonas)
			System.out.println(p);
 
		//Ordenamos
		listaPersonas.sort(null);
 
		System.out.println("\nLista personas ordenadas por edad:");
		for (Persona p: listaPersonas)
			System.out.println(p);
	}
 
}

En pantalla veremos como el ArrayList es capaz de ordenar las Personas correctamente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Lista personas SIN ordenar:
Nombre: Juan -- Edad: 45
Nombre: Sara -- Edad: 38
Nombre: Carmen -- Edad: 49
Nombre: David -- Edad: 22
Nombre: Luis -- Edad: 58
Nombre: Laura -- Edad: 33
Nombre: Fermin -- Edad: 46
Nombre: Soledad -- Edad: 33
 
Lista personas ordenadas por edad:
Nombre: David -- Edad: 22
Nombre: Laura -- Edad: 33
Nombre: Soledad -- Edad: 33
Nombre: Sara -- Edad: 38
Nombre: Juan -- Edad: 45
Nombre: Fermin -- Edad: 46
Nombre: Carmen -- Edad: 49
Nombre: Luis -- Edad: 58

Pruébalo, pregunta lo que no entiendas e intenta aplicarlo al ejercicio que te piden.
Si te atascas o necesitas más ayuda, muestra tu código y te ayudamos a completarlo.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ordenar arraylist

Publicado por Ana (35 intervenciones) el 12/12/2021 00:01:52
Muchas gracias! cuando quiero sobreescribir el metodo compareTo me aparece un error en el @override y me pide borrarlo y el array no se ordena, nose porque sera
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ordenar arraylist

Publicado por Kabuto (1383 intervenciones) el 13/12/2021 00:40:54
Eso es porque no lo estás sobreescribiendo correctamente, sino que lo estarás "sobrecargando"

Me explico:
Ese método, para sobreescribirlo, el dato de retorno y el argumento de entrada (lo que le llega entre paréntesis) han de ser exactamente los mismos que tiene en la clase/interface madre de la cuál proviene

En este caso concreto, el dato de retorno es un int y el argumento de entrada es un objeto Persona

1
2
3
4
5
6
7
8
9
10
@Override
	public int compareTo(Persona otraPersona) {
 
		if (this.edad < otraPersona.edad)
			return -1;
		else if (this.edad > otraPersona.edad)
			return 1;
		else
			return 0; //Tienen la misma edad
	}

Si yo cambiar alguno de esos datos, es perfectamente "legal"..., pero ya no estaría sobreescribiéndolo.
Estaría sobrecargándolo, por ejemplo:

1
2
3
4
5
6
7
8
9
10
@Override
	public double compareTo(Persona otraPersona) {
 
		if (this.edad < otraPersona.edad)
			return -1;
		else if (this.edad > otraPersona.edad)
			return 1;
		else
			return 0; //Tienen la misma edad
	}

Sobrecargar significa que ahora habrían conviviendo dos métodos con exactamente el mismo nombre: compareTo()
Pero son distintos porque sus datos de retorno y/o argumento de entrada son diferentes.
Y hay ocasiones en las que nos puede interesar tener un método sobrecargado, de hecho, es algo habitual. Pero en este caso no nos sirve sobrecargar, necesitamos sobreescribir.

La función de la etiqueta @Override es precisamente comprobar si estamos sobreescribiendo o no.

Si no la ponemos, podríamos estar sobrecargando por error, en lugar de sobreescribir. Y no nos daríamos cuenta.

Pero al ponerla, ya no se permite sobrecargar. Solo va a permitir sobreescribir, siempre que lo hagamos bien claro. Por eso te salió error en la etiqueta @Override, porque algo debiste hacer mal y te avisaba de que NO estabas sobreescribiendo, si no sobrecargando.

Y sobrecargar no va a servir para que el ArrayList ordene, hay que sobreescribir.

Revisa como escribiste el código, o publícalo aquí para que lo revisemos.

Sobre todo comprueba como pusiste la implementación de la interfaz.
En mi código, puse específicamente que solo íbamos a comparar objetos Persona.
1
public class Persona implements Comparable<Persona>

Al ponerlo así, el método compareTo() obligatoriamente ha de recibir un objeto Persona
1
2
@Override
	public int compareTo(Persona otraPersona)


Sin embargo, es muy habitual y lo verás en muchos sitios, que no se especifique la clase final con la que se va a comparar y que se indique la clase Object, que es la superclase madre absoluta

1
public class Persona implements Comparable<Object>

Si por casualidad lo has puesto así, entonces el método compareTo() te va a exigir un argumento de entrada de clase Object para dejarse sobreescribir

1
2
@Override
	public int compareTo(Object otraPersona)

Puede hacerse así, lo único es que luego en el código habrá que instanciar ese Object como Persona para poder hacer las comparaciones.

Pero en cualquier caso, los datos de retorno y entrada del método comparteTo() han de corresponderse con la manera que hayamos implementado la interface Comparable.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar