¿Cómo ordenar una ArrayList?


353

Tengo una lista de dobles en Java y quiero ordenar ArrayList en orden descendente.

Input ArrayList es la siguiente:

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

La salida debería ser así

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

Respuestas:


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

Eso hará lo que quieras. ¡Recuerde importar Collectionssin embargo!

Aquí está la documentación paraCollections .


53
Tal vez vale la pena mencionar que se puede definir su propio Comparator:)
Polygnome

1
@Polygnome El OP solo está ordenando Doubles.
tckmn

3
Sí, pero puede ordenarlos de varias maneras, según el caso de uso. A veces es posible que desee ordenarlos por distancia a 0. Ni siquiera conozco las características de tiempo de ejecución de reverse, pero ordenar descendente en realidad podría ser más rápido que ordenar ascendente y luego revertir. Además, el uso de una implementación de Lista que sea compatible Comparatorcomo argumento de constructor (manteniéndolo invariable) aseguraría que la lista esté ordenada en todo momento.
Polygnome

44
@Ayesha Sí, Collections.sortusa compareTodetrás de escena.
tckmn

45
Uno realmente debería usar Collections.sort(list, Collections.reverseOrder());. Además de ser más idiomático (y posiblemente más eficiente), usar el comparador de orden inverso asegura que el orden sea estable (lo que significa que el orden de los elementos no cambiará cuando sean iguales según el comparador, mientras que la inversión cambiará el orden )
Marco13

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

1
¿Qué debo hacer si CustomData es List<AnotherModel>cuál AnotherModeltiene idy quiero clasificar id? Y solo accedo al CustomData modelo en mi clase.
Dr.jacky

2
Simplemente reemplazaría la clase CustomData con AnotherModel y tendría una línea como esta: return lhs.id> rhs.id? -1: .. etc
user2808054

La declaración de devolución de comparación se puede escribir mejor comoInteger.compare(rhs.customInt, lhs.customInt);
LordKiz

92

Utilice el método util de la clase java.util.Collections , es decir

Collections.sort(list)

De hecho, si desea ordenar objetos personalizados, puede usar

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

ver colecciones api


90

Para su ejemplo, esto hará la magia en Java 8

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

Pero si desea ordenar por algunos de los campos del objeto que está ordenando, puede hacerlo fácilmente:

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

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


¿Dónde se encuentra el método de 'comparación'?
lippo

1
necesita importar: importar static java.util.Comparator.comparing;
krmanish007

1
¿Está disponible con Java 1.7?
lippo

55
No, esto es parte de la secuencia y la interfaz funcional, que es parte de Java 8
krmanish007

1
Tienes razón @AjahnCharles. Han eliminado cero-arg, por lo que he actualizado mi respuesta ahora.
krmanish007

54

Usando lambdas (Java8) y reduciéndolo a la sintaxis más simple (la JVM inferirá mucho en este caso), obtienes:

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

Una versión más detallada:

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

Collections.sort(testList, comp);

El uso de una lambda es posible porque la interfaz del Comparador tiene un solo método para implementar, por lo que la VM puede inferir qué método se está implementando. Dado que los tipos de parámetros pueden inferirse, no es necesario indicarlos (es decir, en (a, b)lugar de hacerlo (Double a, Double b). Y dado que el cuerpo lambda tiene una sola línea, y se espera que el método devuelva un valor, returnse infiere el y las llaves) No son necesarios.


Esto es genial, gracias! Este es un poco más compacto: Collections.sort (testList, Comparator.reverseOrder ());
kavics

Aún más compacto: testList.sort (Comparator.reverseOrder ());
jonasespelita

29

Con Java8 hay un método de clasificación predeterminado en la interfaz de Lista que le permitirá ordenar la colección si proporciona un Comparador. Puede ordenar fácilmente el ejemplo en la pregunta de la siguiente manera:

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

Nota: los argumentos en el lambda se intercambian cuando se pasan a Double.compare para garantizar que el orden descienda


Para mí, esta es la mejor respuesta, ya que también funciona para ordenar usando objetos ... ejemplo locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas

26

Puede usar Collections.sort(list)para ordenar listsi listcontiene Comparableelementos. De lo contrario, le recomendaría implementar esa interfaz como aquí:

public class Circle implements Comparable<Circle> {}

y por supuesto proporcione su propia realización del compareTométodo como aquí:

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

Y luego puede volver a usar Colection.sort(list)como ahora la lista contiene objetos de tipo Comparable y se pueden ordenar. El orden depende del compareTométodo. Consulte este https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html para obtener información más detallada.


11

Collections.sortle permite pasar una instancia de a Comparatorque define la lógica de clasificación. Así que en lugar de ordenar la lista en orden natural y luego darle la vuelta, uno puede simplemente pasar Collections.reverseOrder()a sortfin de ordenar la lista en orden inverso:

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

Como mencionó @ Marco13, además de ser más idiomático (y posiblemente más eficiente), el uso del comparador de orden inverso asegura que el orden sea estable (lo que significa que el orden de los elementos no cambiará cuando sean iguales según el comparador, mientras que la inversión cambiará el orden)


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;

    }
}

parece ser eso es Colecciones.synchronizedList nos ayuda
vitalinvent

7

Aquí hay una breve hoja de trucos que cubre 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))

5

Si está utilizando Java SE 8, esto podría ser de ayuda.

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

66
También existe Collections.reverseOrder()sin ningún argumento, lo que hace que su implementación sea compareDoublesuperflua (es equivalente al orden natural de Doubles). La respuesta aquí debería serCollections.sort(testList, Collections.reverseOrder());
Matt

5

| * | Ordenar una lista:

import java.util.Collections;

| => Ordenar orden de asc:

Collections.sort(NamAryVar);

| => Ordenar orden de Dsc:

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

| * | Invierta el orden de la lista:

Collections.reverse(NamAryVar);

4

Puedes hacer así:

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

Collection tiene un comparador predeterminado que puede ayudarlo con eso.

Además, si desea utilizar algunas características nuevas de Java 8, puede hacer lo siguiente:

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

3

Por ejemplo, tengo una clase Person: String name, int age ==> Constructor new Person (name, age)

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

En JAVA 8 es mucho más fácil ahora.

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 esto

.sorted(Comparator.reverseOrder())

3

Puedes usar así

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

1

Con Eclipse Collections puede crear una lista doble primitiva, ordenarla y luego invertirla para ponerla en orden descendente. Este enfoque evitaría boxear los dobles.

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

Si quieres un List<Double>, entonces lo siguiente funcionaría.

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

Si desea mantener el tipo como ArrayList<Double>, puede inicializar y ordenar la lista utilizando la ArrayListIterateclase de utilidad de la siguiente manera:

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

Nota: Soy un committer para Eclipse Collections .


1

La siguiente línea debería hacer el grueso

testList.sort(Collections.reverseOrder());
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.