Aprendi a usar o comparável, mas estou tendo dificuldades com o comparador. Estou com um erro no meu 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)
Aqui está o meu 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));
}
}
}
Acredito que tenha algo a ver com o vazamento no método de comparação, mas eu estava brincando com ele e ainda não consegui encontrar a solução
java
sorting
comparator
Dan
fonte
fonte
Comparator<People>
,Comparable<People>
,List<People>
, etc.sort
. Se você for instruído a usarComparator<People>
, use o argumento 2sort
, não o argumento 1sort
(que requerPeople implements Comparable<People>
).Respostas:
Existem algumas coisas estranhas na sua classe de exemplo:
price
einfo
(mais algo para objetos, não para pessoas);De qualquer forma, aqui está uma demonstração de como usar um
Comparator<T>
:EDITAR
E uma demonstração equivalente do Java 8 ficaria assim:
fonte
a.age - b.age
int
stackoverflow.com/questions/2728793/...Comparable
, você deve escolher um único atributo para comparar. No caso de uma pessoa, existem muitos atributos que podem ser comparados: idade, comprimento, sexo, nomes etc. Nesse caso, é fácil fornecer alguns comparadores que realizam essas comparações.Aqui está um modelo super curto para fazer a classificação imediatamente:
se for difícil de lembrar, tente apenas lembrar que é semelhante (em termos do sinal do número) a:
Nesse caso, você deseja classificar em ordem crescente: do menor para o maior número.
fonte
compare()
sempre.Use em
People implements Comparable<People>
vez disso; isso define a ordem natural paraPeople
.A
Comparator<People>
também pode ser definida além disso, masPeople implements Comparator<People>
não é a maneira correta de fazer as coisas.As duas sobrecargas para
Collections.sort
são diferentes:<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
objetos usando sua ordem natural<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
Você está confundindo os dois tentando classificar um
Comparator
(que é novamente o motivo pelo qual não faz sentidoPerson implements Comparator<Person>
). Novamente, para usarCollections.sort
, você precisa de um destes para ser verdade:Comparable
(use o 1-argsort
)Comparator
para o tipo deve ser fornecido (use os 2-argssort
)Perguntas relacionadas
Além disso, não use tipos brutos no novo código . Os tipos brutos não são seguros e são fornecidos apenas para compatibilidade.
Ou seja, em vez disso:
você deveria ter usado a declaração genérica typesafe assim:
Você verá que seu código nem compila !! Isso seria uma coisa boa, porque há algo errado com o código (
Person
nãoimplements Comparable<Person>
), mas como você usou o tipo bruto, o compilador não verificou isso e, em vez disso, você recebe umClassCastException
em tempo de execução !!!Isso deve convencê-lo a sempre usar tipos genéricos typesafe no novo código. Sempre.
Veja também
fonte
Por uma questão de integridade, aqui está um
compare
método simples de uma linha :fonte
signum
Integer.compare(lhs.getId(), rhs.getId());
é uma abordagem melhor. Como @ niraj.nijju mencionado, a subtração pode causar estouro.O Java 8 adicionou uma nova maneira de fazer comparadores que reduz a quantidade de código que você precisa escrever, Comparator.comparing . Também confira Comparator.reversed
Aqui está uma amostra
fonte
Você deseja implementar o comparável, não o comparador. Você precisa implementar o método compareTo. Você está perto embora. O comparador é uma rotina de comparação de "terceiros". Comparável é que esse objeto pode ser comparado com outro.
Observe que você pode procurar nulos aqui para getId .. apenas no caso.
fonte
Aqui está um exemplo de um comparador que funcionará para qualquer método de zero arg que retorne um comparável. Existe algo assim em um jdk ou biblioteca?
fonte
Por uma questão de completude.
Usando Java8
se você quiser
descending order
fonte
People::getId
?.thenComparing()
cláusula quando houver um conflito..thenComparing()
?fonte
A solução pode ser otimizada da seguinte maneira: Primeiro, use uma classe interna privada, pois o escopo dos campos é ser a classe envolvente TestPeople, para que a implementação da classe People não seja exposta ao mundo exterior. Isso pode ser entendido em termos de criação de uma API que espera uma lista classificada de pessoas. Em segundo lugar, usando a expressão Lamba (java 8) que reduz o código e, portanto, o esforço de desenvolvimento
Portanto, o código seria o seguinte:
fonte
Você deve usar o método de classificação sobrecarregada (peps, new People ())
fonte
Aqui está a minha resposta para uma ferramenta comparadora simples
}
Ferramenta Utilitária para o mesmo
}
Classe de informações da coluna
fonte
Duas correções:
Você precisa criar um
ArrayList
dosPeople
objetos:Depois de adicionar os objetos às preparações, use:
Além disso, adicione uma
CompareId
classe como:fonte
Não perca tempo implementando o Algoritmo de Classificação por conta própria. Em vez de; usar
Collections.sort () para classificar os dados.
fonte