Aprendí a usar el comparable pero estoy teniendo dificultades con el Comparador. Tengo un error en mi código:
Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at New.TestPeople.main(TestPeople.java:18)
Aquí está mi código:
import java.util.Comparator;
public class People implements Comparator {
private int id;
private String info;
private double price;
public People(int newid, String newinfo, double newprice) {
setid(newid);
setinfo(newinfo);
setprice(newprice);
}
public int getid() {
return id;
}
public void setid(int id) {
this.id = id;
}
public String getinfo() {
return info;
}
public void setinfo(String info) {
this.info = info;
}
public double getprice() {
return price;
}
public void setprice(double price) {
this.price = price;
}
public int compare(Object obj1, Object obj2) {
Integer p1 = ((People) obj1).getid();
Integer p2 = ((People) obj2).getid();
if (p1 > p2) {
return 1;
} else if (p1 < p2){
return -1;
} else {
return 0;
}
}
}
import java.util.ArrayList;
import java.util.Collections;
public class TestPeople {
public static void main(String[] args) {
ArrayList peps = new ArrayList();
peps.add(new People(123, "M", 14.25));
peps.add(new People(234, "M", 6.21));
peps.add(new People(362, "F", 9.23));
peps.add(new People(111, "M", 65.99));
peps.add(new People(535, "F", 9.23));
Collections.sort(peps);
for (int i = 0; i < peps.size(); i++){
System.out.println(peps.get(i));
}
}
}
Creo que tiene que ver algo con el casting en el método de comparación, pero estaba jugando con él y todavía no podía encontrar la solución
java
sorting
comparator
Dan
fuente
fuente
Comparator<People>
,Comparable<People>
,List<People>
, etc.sort
. Si le dicen que useComparator<People>
, use el argumento 2sort
, no el argumento 1sort
(que requierePeople implements Comparable<People>
).Respuestas:
Hay un par de cosas incómodas con su clase de ejemplo:
price
yinfo
(más algo para objetos, no personas);De todos modos, aquí hay una demostración de cómo usar un
Comparator<T>
:EDITAR
Y una demostración equivalente de Java 8 se vería así:
fuente
a.age - b.age
int
stackoverflow.com/questions/2728793/…Comparable
, debe elegir un solo atributo para compararlo. En el caso de una persona, hay muchos atributos con los que se puede comparar: edad, longitud, género, nombres, etc. En ese caso, es fácil proporcionar un par de comparadores que realicen estas comparaciones.Aquí hay una plantilla súper corta para ordenar de inmediato:
Si es difícil de recordar, intente recordar que es similar (en términos del signo del número) a:
Eso es en caso de que desee ordenar en orden ascendente: del número más pequeño al más grande.
fuente
compare()
todas.Usar en su
People implements Comparable<People>
lugar; Esto define el orden natural paraPeople
.A
Comparator<People>
también se puede definir además, peroPeople implements Comparator<People>
no es la forma correcta de hacer las cosas.Las dos sobrecargas para
Collections.sort
son diferentes:<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
objetos usando su orden natural<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
Estás confundiendo a los dos tratando de ordenar un
Comparator
(lo cual es nuevamente el por qué no tiene sentidoPerson implements Comparator<Person>
) Una vez más, para usarCollections.sort
, necesita uno de estos para ser cierto:Comparable
(use el 1-argsort
)Comparator
debe proporcionar una A para el tipo (use los 2 argssort
)Preguntas relacionadas
Además, no use tipos sin formato en el nuevo código . Los tipos sin formato no son seguros y solo se proporcionan por compatibilidad.
Es decir, en lugar de esto:
deberías haber usado la declaración genérica typesafe como esta:
¡Entonces descubrirás que tu código ni siquiera se compila! Eso sería una buena cosa, porque hay algo mal con el código (
Person
no lo haceimplements Comparable<Person>
), pero debido a que usó el tipo sin formato, el compilador no lo comprobó , ¡y en su lugar obtiene unClassCastException
tiempo de ejecución!Esto debería convencerlo de que siempre use tipos genéricos typesafe en el nuevo código. Siempre.
Ver también
fuente
En aras de la integridad, aquí hay un
compare
método simple de una sola línea :fuente
signum
Integer.compare(lhs.getId(), rhs.getId());
Es un mejor enfoque. Como @ niraj.nijju mencionó, la resta puede causar desbordamiento.Java 8 agregó una nueva forma de hacer comparadores que reduce la cantidad de código que tiene que escribir, comparando.comparing . También echa un vistazo a Comparator.reversed
Aquí hay una muestra
fuente
Desea implementar Comparable, no Comparator. Necesita implementar el método compareTo. Sin embargo, estás cerca. Comparator es una rutina de comparación de "terceros". Comparable es que este objeto se puede comparar con otro.
Tenga en cuenta que es posible que desee verificar nulos aquí para getId ... por si acaso.
fuente
Aquí hay un ejemplo de un Comparador que funcionará para cualquier método de arg cero que devuelva un Comparable. ¿Existe algo como esto en un jdk o biblioteca?
fuente
En aras de la exhaustividad.
Usando Java8
si quieres en
descending order
fuente
People::getId
?.thenComparing()
cláusula cuando hay un choque..thenComparing()
?fuente
La solución se puede optimizar de la siguiente manera: en primer lugar, use una clase interna privada ya que el alcance de los campos debe ser la clase adjunta TestPeople para que la implementación de la clase People no quede expuesta al mundo exterior. Esto se puede entender en términos de crear una API que espera una lista ordenada de personas. En segundo lugar, usar la expresión de Lamba (java 8) que reduce el código, por lo tanto, el esfuerzo de desarrollo
Por lo tanto, el código sería el siguiente:
fuente
Debe usar el método de ordenación sobrecargado (peps, personas nuevas)
fuente
Aquí está mi respuesta para una herramienta de comparación simple
}
Herramienta de utilidad para el mismo
}
Clase de información de columna
fuente
Dos correcciones:
Tienes que hacer un
ArrayList
dePeople
objetos:Después de agregar los objetos a las preparaciones, use:
Además, agregue una
CompareId
clase como:fuente
No pierda el tiempo implementando el algoritmo de clasificación por su cuenta. En lugar; utilizar
Collections.sort () para ordenar los datos.
fuente