Eu tenho matriz de objetos person (int age; String name;)
.
Como posso classificar essa matriz em ordem alfabética por nome e depois por idade?
Qual algoritmo você usaria para isso?
Você pode usar da Collections.sort
seguinte maneira:
private static void order(List<Person> persons) {
Collections.sort(persons, new Comparator() {
public int compare(Object o1, Object o2) {
String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);
if (sComp != 0) {
return sComp;
}
Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}});
}
List<Persons>
agora é classificado por nome e depois por idade.
String.compareTo
"Compara duas strings lexicograficamente" - dos documentos .
Collections.sort
é um método estático na biblioteca de coleções nativa. Ele faz a classificação real, você só precisa fornecer um Comparador que define como dois elementos da sua lista devem ser comparados: isso é conseguido fornecendo sua própria implementação do compare
método.
Comparator
para evitar a necessidade de converter as entradas.Comparable
. Veja a resposta por @ berry120Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparingInt(Person::getAge);
Para aqueles capazes de usar a API de streaming Java 8, existe uma abordagem mais limpa que está bem documentada aqui: Lambdas e classificação
Eu estava procurando o equivalente do C # LINQ:
Encontrei o mecanismo no Java 8 no comparador:
Então, aqui está o trecho que demonstra o algoritmo.
Confira o link acima para obter uma maneira mais clara e uma explicação sobre como a inferência de tipo do Java torna um pouco mais difícil de definir em comparação com o LINQ.
Aqui está o teste de unidade completo para referência:
fonte
Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparing(Person::getAge);
thenComparingInt
for age (int)Collections.sort(people, comparator);
?Usando a abordagem Java 8 Streams ...
E a abordagem Java 8 Lambda ...
Por fim ...
fonte
Você precisa implementar o seu próprio
Comparator
e usá-lo: por exemploO seu comparador pode ficar assim:
O comparador primeiro compara os nomes; se eles não são iguais, retorna o resultado da comparação; caso contrário, retorna o resultado da comparação ao comparar as idades de ambas as pessoas.
Esse código é apenas um rascunho: como a classe é imutável, você pode pensar em criar um único nome, em vez de criar uma nova instância para cada classificação.
fonte
Você pode usar a abordagem Java 8 Lambda para conseguir isso. Como isso:
fonte
Faça sua classe pessoal implementar
Comparable<Person>
e, em seguida, implemente o método compareTo, por exemplo:Isso será classificado primeiro pelo nome (sem distinção entre maiúsculas e minúsculas) e depois por idade. Em seguida, você pode executar
Arrays.sort()
ouCollections.sort()
na coleção ou matriz de objetos Pessoa.fonte
Goiaba
ComparisonChain
fornece uma maneira limpa de fazê-lo. Consulte este link .Um utilitário para executar uma instrução de comparação encadeada. Por exemplo:
fonte
Você pode fazer assim:
fonte
Use
Comparator
e em seguida, colocar objetos emCollection
, em seguida,Collections.sort();
fonte
Crie quantos comparadores forem necessários. Depois, chame o método "thenComparing" para cada categoria de pedido. É uma maneira de fazer pelo Streams. Vejo:
Look: classifique o objeto definido pelo usuário em vários campos - Comparador (fluxo lambda)
fonte
Eu tomaria cuidado ao usar o Guava's,
ComparisonChain
pois ele cria uma instância por elemento que foi comparada, para que você analise a criação deN x Log N
cadeias de comparação apenas para comparar se estiver classificando ouN
instâncias se estiver repetindo e verificando a igualdade.Em vez disso, eu criaria uma estática
Comparator
usando a API Java 8 mais recente, se possível, ou aOrdering
API do Guava, que permite fazer isso, aqui está um exemplo com o Java 8:Aqui está como usar a
Ordering
API do Guava : https://github.com/google/guava/wiki/OrderingExplainedfonte
compare
método não cria nada, mas retorna uma das instâncias singletonLESS
,GREATER
ouACTIVE
dependendo do resultado da comparação. Essa é uma abordagem altamente otimizada e não adiciona sobrecarga de memória ou desempenho.Ou você pode explorar o fato de que
Collections.sort()
(ouArrays.sort()
) é estável (não reordena elementos iguais) e usa umComparator
para classificar por idade primeiro e depois outro para classificar por nome.Nesse caso específico, essa não é uma ideia muito boa, mas se você precisar alterar a ordem de classificação em tempo de execução, pode ser útil.
fonte
Você pode usar o comparador serial genérico para classificar coleções por vários campos.
fonte
Versão atualizada:
fonte
Para uma classe
Book
como esta:classificando a classe principal com objetos simulados
fonte
Não tenho certeza se é feio escrever o compartimento dentro da classe Person neste caso. Fez assim:
fonte