Come ordinare un ArrayList?


353

Ho un elenco di doppi in Java e voglio ordinare ArrayList in ordine decrescente.

Input ArrayList è il seguente:

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);

L'output dovrebbe essere così

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

Risposte:


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

Quello farà quello che vuoi. Ricorda di importare Collectionsperò!

Ecco la documentazione perCollections .


53
Forse vale la pena ricordare che puoi definire il tuo Comparator:)
Polygnome,

1
@Polygnome L'OP sta ordinando solo Doubles.
martedì

3
Sì, ma è possibile ordinarli in vari modi, a seconda del caso d'uso. A volte potresti volerli ordinare per distanza a 0. Non so nemmeno delle caratteristiche di runtime di reverse, ma l'ordinamento in ordine decrescente potrebbe effettivamente essere più veloce dell'ordinamento in ordine crescente e quindi invertendo. Inoltre, l'utilizzo di un'implementazione dell'elenco che supporta Comparatorcome argomento del costruttore (mantenendolo così invariante) assicurerebbe che l'elenco sia ordinato in ogni momento.
Polygnome,

4
@Ayesha Sì, Collections.sortutilizza compareTodietro le quinte.
martedì

45
Uno dovrebbe effettivamente usare Collections.sort(list, Collections.reverseOrder());. Oltre ad essere più idiomatico (e forse più efficiente), l'uso del comparatore di ordine inverso assicura che l'ordinamento sia stabile (il che significa che l'ordine degli elementi non verrà modificato quando sono uguali in base al comparatore, mentre l'inversione cambierà l'ordine ).
Marco13

134

Discendente:

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;
    }
});

1
Cosa devo fare se CustomData è quello List<AnotherModel>che AnotherModelha ide voglio ordinare per id? E ho solo accesso al CustomData modello nella mia classe.
Dr.jacky,

2
Sostituiresti semplicemente la classe CustomData con AnotherModel e avresti una linea come questa: return lhs.id> rhs.id? -1: .. ecc.
user2808054,

La dichiarazione di ritorno di confronto può essere meglio scritta comeInteger.compare(rhs.customInt, lhs.customInt);
LordKiz

92

Utilizzare il metodo util della classe java.util.Collections , ad es

Collections.sort(list)

In effetti, se si desidera ordinare oggetti personalizzati, è possibile utilizzare

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

vedi le raccolte api


90

Per il tuo esempio, questo farà la magia in Java 8

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

Ma se vuoi ordinare per alcuni dei campi dell'oggetto che stai ordinando, puoi farlo facilmente:

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

o

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

o

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

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


Dove si trova il metodo di "confronto"?
lippo,

1
devi importare: import static java.util.Comparator.comparing;
Krmanish007,

1
È disponibile con Java 1.7?
lippo,

5
No, questa è una parte dello stream e dell'interfaccia funzionale, che fa tutto parte di Java 8
krmanish007

1
Hai ragione @AjahnCharles. Hanno rimosso zero-arg, quindi ho aggiornato la mia risposta ora.
Krmanish007

54

Usando lambdas (Java8) e riducendolo al minimo della sintassi ( in questo caso la JVM ne inferirà un sacco ), otterrai:

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

Una versione più dettagliata:

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

Collections.sort(testList, comp);

L'uso di un lambda è possibile perché l'interfaccia del comparatore ha un solo metodo da implementare, quindi la VM può dedurre quale metodo sta implementando. Poiché i tipi di parametri possono essere dedotti, non è necessario dichiararli (ovvero (a, b)invece di (Double a, Double b). E poiché il corpo lambda ha solo una riga e si prevede che il metodo restituisca un valore, returnviene dedotto e le parentesi graffe non sono necessari.


È fantastico, grazie! Questo è un po 'più compatto: Collections.sort (testList, Comparator.reverseOrder ());
kavics,

Ancora più compatto: testList.sort (Comparator.reverseOrder ());
jonasespelita,

29

Con Java8 esiste un metodo di ordinamento predefinito sull'interfaccia Elenco che consente di ordinare la raccolta se si fornisce un comparatore. Puoi facilmente ordinare l'esempio nella domanda come segue:

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

Nota: gli arg in lambda vengono scambiati quando passati a Double.compare per assicurarsi che l'ordinamento stia scendendo


Per me questa è la risposta migliore in quanto funziona anche per l'ordinamento usando oggetti ... esempio locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas

26

È possibile utilizzare Collections.sort(list)per ordinare listse listcontiene Comparableelementi. Altrimenti ti consiglierei di implementare quell'interfaccia come qui:

public class Circle implements Comparable<Circle> {}

e ovviamente fornisci la tua realizzazione del compareTometodo come qui:

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

E quindi è possibile utilizzare nuovamente Colection.sort(list)poiché l'elenco ora contiene oggetti di tipo Comparabile e può essere ordinato. L'ordine dipende dal compareTometodo. Controlla questo https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html per informazioni più dettagliate.


11

Collections.sortconsente di passare un'istanza di a Comparatorche definisce la logica di ordinamento. Quindi, invece di ordinare l'elenco in ordine naturale e quindi invertirlo, si può semplicemente passare Collections.reverseOrder()a sortal fine di ordinare l'elenco in ordine inverso:

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

Come menzionato da @ Marco13, oltre ad essere più idiomatico (e forse più efficiente), l'utilizzo del comparatore di ordine inverso assicura che l'ordinamento sia stabile (il che significa che l'ordine degli elementi non verrà modificato quando sono uguali in base al comparatore, mentre l'inversione cambierà l'ordine)


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;

    }
}

sembra essere il loro è Collections.synchronizedList ci aiuta
vitalinvent

7

Ecco un breve cheatsheet che copre casi tipici:

// 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))

5

se si utilizza Java SE 8, questo potrebbe essere di aiuto.

//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);

6
C'è anche Collections.reverseOrder()senza alcun argomento, il che rende compareDoublesuperflua la tua implementazione (è equivalente all'ordinamento naturale di Doubles). La risposta qui dovrebbe essereCollections.sort(testList, Collections.reverseOrder());
Matt,

5

| * | Ordinamento di un elenco:

import java.util.Collections;

| => Ordina ordine asc:

Collections.sort(NamAryVar);

| => Ordina ordine Dsc:

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

| * | Invertire l'ordine dell'elenco:

Collections.reverse(NamAryVar);

4

Puoi fare così:

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

Collection ha un comparatore predefinito che può aiutarti in questo.

Inoltre, se vuoi usare alcune nuove funzionalità di Java 8, puoi fare così:

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

3

Ad esempio ho una classe Person: String name, int age ==> Costruttore nuova persona (nome, età)

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]]

}

if you want to short by name->if you want to sort by name
linrongbin

3

In JAVA 8 ora è molto semplice.

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]

- Per il retro, utilizzare questo

.sorted(Comparator.reverseOrder())

3

Puoi usare così

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

1

Con Eclipse Collections puoi creare un doppio elenco primitivo, ordinarlo e quindi invertirlo per metterlo in ordine decrescente. Questo approccio eviterebbe di inscatolare i doppi.

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 si desidera un List<Double>, quindi quanto segue funzionerebbe.

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 si desidera mantenere il tipo come ArrayList<Double>, è possibile inizializzare e ordinare l'elenco utilizzando la ArrayListIterateclasse di utilità come segue:

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

Nota: sono un committer per le raccolte Eclipse .


1

La seguente riga dovrebbe fare lo spessore

testList.sort(Collections.reverseOrder());
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.