Como classificar um ArrayList?

352

Eu tenho uma lista de duplas em java e quero classificar ArrayList em ordem decrescente.

ArrayList de entrada é como abaixo:

List<Double> testList = new ArrayList();

testList.add(0.5);
testList.add(0.2);
testList.add(0.9);
testList.add(0.1);
testList.add(0.1);
testList.add(0.1);
testList.add(0.54);
testList.add(0.71);
testList.add(0.71);
testList.add(0.71);
testList.add(0.92);
testList.add(0.12);
testList.add(0.65);
testList.add(0.34);
testList.add(0.62);

A saída deve ser assim

0.92
0.9
0.71
0.71
0.71
0.65
0.62
0.54
0.5
0.34
0.2
0.12
0.1
0.1
0.1
Himanshu
fonte

Respostas:

524
Collections.sort(testList);
Collections.reverse(testList);

Isso fará o que você quiser. Lembre-se de importar Collections!

Aqui está a documentação paraCollections .

tckmn
fonte
53
Talvez vale a pena mencionar que você pode definir seu próprio Comparator:)
Polygnome
11
@ Polygnome O OP está apenas classificando Doubles.
usar o seguinte comando
3
Sim, mas você pode classificá-los de várias maneiras, dependendo do caso de uso. Às vezes, você pode classificá-los por distância a 0. Eu nem sei sobre as características de tempo de execução reverse, mas a ordenação descendente pode ser mais rápida do que a ordenação ascendente e a inversão. Além disso, o uso de uma implementação de Lista que suporta Comparatorcomo argumento construtor (mantendo-o invariável) garantiria que a lista fosse classificada o tempo todo.
precisa saber é o seguinte
4
@ Ayesha Sim, Collections.sortusa compareTonos bastidores.
precisa saber é
45
Deve-se realmente usar Collections.sort(list, Collections.reverseOrder());. Além de ser mais idiomático (e possivelmente mais eficiente), o uso do comparador de ordem inversa garante que a classificação seja estável (o que significa que a ordem dos elementos não será alterada quando forem iguais de acordo com o comparador, enquanto a reversão mudará a ordem )
precisa saber é o seguinte
134

Descendente:

Collections.sort(mArrayList, new Comparator<CustomData>() {
    @Override
    public int compare(CustomData lhs, CustomData rhs) {
        // -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
        return lhs.customInt > rhs.customInt ? -1 : (lhs.customInt < rhs.customInt) ? 1 : 0;
    }
});
bong jae choe
fonte
11
O que devo fazer se CustomData é List<AnotherModel>qual AnotherModeltem ide quero classificar por id? E acabei de acessar o CustomData modelo na minha turma.
Dr.jacky
2
Você acabou de substituir a classe CustomData por AnotherModel e ter uma linha como esta: return lhs.id> rhs.id? -1: .. etc
user2808054
A declaração de retorno de comparação pode ser melhor redigida comoInteger.compare(rhs.customInt, lhs.customInt);
LordKiz 13/08/19
92

Use o método util da classe java.util.Collections , ou seja,

Collections.sort(list)

De fato, se você deseja classificar objetos personalizados, pode usar

Collections.sort(List<T> list, Comparator<? super T> c) 

ver coleções api

M Sach
fonte
90

Para o seu exemplo, isso fará a mágica no Java 8

List<Double> testList = new ArrayList();
testList.sort(Comparator.naturalOrder());

Mas se você deseja classificar por alguns dos campos do objeto que está classificando, pode fazê-lo facilmente:

testList.sort(Comparator.comparing(ClassName::getFieldName));

ou

 testList.sort(Comparator.comparing(ClassName::getFieldName).reversed());

ou

 testList.stream().sorted(Comparator.comparing(ClassName::getFieldName).reversed()).collect(Collectors.toList());

Fontes: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

krmanish007
fonte
Onde está localizado o método de comparação?
Lippo # 4/16
11
você precisa importar: import static java.util.Comparator.comparing;
precisa saber é o seguinte
11
Está disponível com Java 1.7?
Lippo #
5
Não, isso faz parte do fluxo e da interface funcional, que faz parte do Java 8
krmanish007
11
Você está certo @AjahnCharles. Eles removeram zero-arg, por isso atualizei minha resposta agora.
krmanish007
54

Usando lambdas (Java8) e reduzindo-o até a menor sintaxe (a JVM inferirá bastante nesse caso), você obtém:

Collections.sort(testList, (a, b) -> b.compareTo(a));

Uma versão mais detalhada:

// Implement a reverse-order Comparator by lambda function
Comparator<Double> comp = (Double a, Double b) -> {
    return b.compareTo(a);
};

Collections.sort(testList, comp);

O uso de um lambda é possível porque a interface do Comparator possui apenas um único método para implementar, para que a VM possa inferir qual método está implementando. Como os tipos de parâmetros podem ser inferidos, eles não precisam ser especificados (ou seja, em (a, b)vez de(Double a, Double b) . E como o corpo lambda possui apenas uma linha, e o método deve retornar um valor, o valor returné inferido e as chaves) não são necessários.

cyrus
fonte
Isso é legal, obrigado! Este é um pouco mais compacto: Collections.sort (testList, Comparator.reverseOrder ());
Kavics
Ainda mais compacto: testList.sort (Comparator.reverseOrder ());
Jonasespelita
29

No Java8, existe um método de classificação padrão na interface da Lista que permitirá que você classifique a coleção se você fornecer um Comparador. Você pode facilmente classificar o exemplo na pergunta da seguinte maneira:

testList.sort((a, b) -> Double.compare(b, a));

Nota: os argumentos no lambda são trocados quando passados ​​para o Double.compare para garantir que a classificação seja decrescente

robjwilkins
fonte
Para mim, esta é a melhor resposta, pois também funciona para classificar usando objetos ... exemplo locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas
26

Você pode usar Collections.sort(list)para classificar listse o seu listcontém Comparableelementos. Caso contrário, eu recomendaria que você implementasse essa interface como aqui:

public class Circle implements Comparable<Circle> {}

e, é claro, forneça sua própria realização do compareTométodo, como aqui:

@Override
    public int compareTo(Circle another) {
        if (this.getD()<another.getD()){
            return -1;
        }else{
            return 1;
        }
    }

E então você pode usar novamente Colection.sort(list)como agora a lista contém objetos do tipo Comparável e pode ser classificada. A ordem depende do compareTométodo. Verifique este https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html para obter informações mais detalhadas.

Yuriy
fonte
11

Collections.sortpermite passar uma instância de uma Comparatorque define a lógica de classificação. Portanto, em vez de classificar a lista em ordem natural e depois revertê-la, basta passar Collections.reverseOrder()para a sortordem de classificação inversa:

// import java.util.Collections;
Collections.sort(testList, Collections.reverseOrder());

Conforme mencionado por @ Marco13, além de ser mais idiomático (e possivelmente mais eficiente), o uso do comparador de ordem inversa garante que a classificação seja estável (o que significa que a ordem dos elementos não será alterada quando forem iguais, de acordo com o comparador, enquanto a reversão mudará a ordem)

Matt
fonte
9
//Here is sorted List alphabetically with syncronized

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * @author manoj.kumar
 */
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
        synchronizedList.add(new Employee("Aditya"));
        synchronizedList.add(new Employee("Siddharth"));
        synchronizedList.add(new Employee("Manoj"));
        Collections.sort(synchronizedList, new Comparator() {
            public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
                //use instanceof to verify the references are indeed of the type in question
                return ((Employee) synchronizedListOne).name
                        .compareTo(((Employee) synchronizedListTwo).name);
            }
        }); 
    /*for( Employee sd : synchronizedList) {
    log.info("Sorted Synchronized Array List..."+sd.name);
    }*/

        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<Employee> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
            }
        }

    }
}

class Employee {
    String name;

    Employee(String name) {
        this.name = name;

    }
}
Hitesh sapra
fonte
parece ser thas é Collections.synchronizedList nos ajuda
vitalinvent
7

Aqui está uma pequena folha de dicas que cobre casos típicos:

// sort
list.sort(naturalOrder())

// sort (reversed)
list.sort(reverseOrder())

// sort by field
list.sort(comparing(Type::getField))

// sort by field (reversed)
list.sort(comparing(Type::getField).reversed())

// sort by int field
list.sort(comparingInt(Type::getIntField))

// sort by double field (reversed)
list.sort(comparingDouble(Type::getDoubleField).reversed())

// sort by nullable field (nulls last)
list.sort(comparing(Type::getNullableField, nullsLast(naturalOrder())))

// two-level sort
list.sort(comparing(Type::getField1).thenComparing(Type::getField2))
ZhekaKozlov
fonte
5

se você estiver usando o Java SE 8, isso pode ser útil.

//create a comparator object using a Lambda expression
Comparator<Double> compareDouble = (d1, d2) -> d1.compareTo(d2);

//Sort the Collection in this case 'testList' in reverse order
Collections.sort(testList, Collections.reverseOrder(compareDouble));

//print the sorted list using method reference only applicable in SE 8
testList.forEach(System.out::println);
Franklin Okeme
fonte
6
Também Collections.reverseOrder()não há argumentos, o que torna sua implementação decompareDouble supérflua (é equivalente à ordenação natural de Doubles). A resposta aqui deve serCollections.sort(testList, Collections.reverseOrder());
Matt
5

| * | Classificando uma lista:

import java.util.Collections;

| => Classificar ordem crescente:

Collections.sort(NamAryVar);

| => Classificar ordem Dsc:

Collections.sort(NamAryVar, Collections.reverseOrder());

| * | Inverta a ordem da lista:

Collections.reverse(NamAryVar);
Sujay UN
fonte
4

Você pode fazer assim:

List<String> yourList = new ArrayList<String>();
Collections.sort(yourList, Collections.reverseOrder());

A coleção possui um comparador padrão que pode ajudá-lo com isso.

Além disso, se você quiser usar alguns novos recursos do Java 8, poderá fazer o seguinte:

List<String> yourList = new ArrayList<String>();
yourList = yourList.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
Thiago
fonte
3

Por exemplo, eu tenho uma classe Person: String name, int age ==> Construtor new Person (nome, idade)

import java.util.Collections;
import java.util.ArrayList;
import java.util.Arrays;


public void main(String[] args){
    Person ibrahima=new Person("Timera",40);
    Person toto=new Person("Toto",35);
    Person alex=new Person("Alex",50);
    ArrayList<Person> myList=new ArrayList<Person>
    Collections.sort(myList, new Comparator<Person>() {
        @Override
        public int compare(Person p1, Person p2) {
            // return p1.age+"".compareTo(p2.age+""); //sort by age
            return p1.name.compareTo(p2.name); // if you want to short by name
        }
    });
    System.out.println(myList.toString());
    //[Person [name=Alex, age=50], Person [name=Timera, age=40], Person [name=Toto, age=35]]
    Collections.reverse(myList);
    System.out.println(myList.toString());
    //[Person [name=Toto, age=35], Person [name=Timera, age=40], Person [name=Alex, age=50]]

}
Ibrahima Timera
fonte
if you want to short by name->if you want to sort by name
linrongbin
3

No JAVA 8, é muito fácil agora.

List<String> alphaNumbers = Arrays.asList("one", "two", "three", "four");
List<String> alphaNumbersUpperCase = alphaNumbers.stream()
    .map(String::toUpperCase)
    .sorted()
    .collect(Collectors.toList());
System.out.println(alphaNumbersUpperCase); // [FOUR, ONE, THREE, TWO]

- Para uso inverso,

.sorted(Comparator.reverseOrder())
Appesh
fonte
3

Você pode usar assim

ArrayList<Group> groupList = new ArrayList<>();
Collections.sort(groupList, Collections.reverseOrder());
Collections.reverse(groupList);
gautam manikant
fonte
1

Com o Eclipse Collections, você pode criar uma lista dupla primitiva, classificá-la e, em seguida, inverter para colocá-la em ordem decrescente. Essa abordagem evitaria o boxe das duplas.

MutableDoubleList doubleList =
    DoubleLists.mutable.with(
        0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
        0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
        .sortThis().reverseThis();
doubleList.each(System.out::println);

Se você deseja um List<Double>, o seguinte funcionaria.

List<Double> objectList =
    Lists.mutable.with(
        0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
        0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
        .sortThis(Collections.reverseOrder());
objectList.forEach(System.out::println);

Se você deseja manter o tipo como ArrayList<Double>, pode inicializar e classificar a lista usando a ArrayListIterateclasse de utilitário da seguinte maneira:

ArrayList<Double> arrayList =
    ArrayListIterate.sortThis(
            new ArrayList<>(objectList), Collections.reverseOrder());
arrayList.forEach(System.out::println);

Nota: Sou um colaborador das Coleções Eclipse .

Donald Raab
fonte
1

A linha a seguir deve fazer a espessura

testList.sort(Collections.reverseOrder());
Ivan Kovtun
fonte