Comment trier une ArrayList?


353

J'ai une liste de doubles en java et je veux trier ArrayList dans l'ordre décroissant.

Input ArrayList est comme ci-dessous:

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

Le résultat devrait être comme ça

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

Réponses:


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

Cela fera ce que vous voulez. Rappelez - vous d'importer Collectionsbien!

Voici la documentation deCollections .


53
Peut-être qu'il vaut la peine de mentionner que vous pouvez définir le vôtre Comparator:)
Polygnome

1
@Polygnome L'OP trie uniquement les Doubles.
tckmn le

3
Oui, mais vous pouvez les trier de différentes manières, selon le cas d'utilisation. Parfois, vous voudrez peut-être les trier par distance à 0. Je ne connais même pas les caractéristiques d'exécution de reverse, mais le tri décroissant pourrait en fait être plus rapide que le tri ascendant puis l'inverse. De plus, l'utilisation d'une implémentation List qui prend Comparatoren charge comme argument constructeur (la gardant ainsi invariante) garantirait que la liste est triée à tout moment.
Polygnome

4
@Ayesha Oui, Collections.sortutilise compareTodans les coulisses.
tckmn

45
Il faut réellement utiliser Collections.sort(list, Collections.reverseOrder());. En plus d'être plus idiomatique (et peut-être plus efficace), l'utilisation du comparateur d'ordre inverse garantit que le tri est stable (ce qui signifie que l'ordre des éléments ne sera pas changé lorsqu'ils sont égaux selon le comparateur, alors que l'inversion changera l'ordre ).
Marco13

134

Descendant:

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
Que dois-je faire si CustomData c'est List<AnotherModel>qui AnotherModela idet je veux trier par id? Et je viens d'accéder au CustomData modèle dans ma classe.
Dr.jacky

2
Vous devez simplement remplacer la classe CustomData par AnotherModel et avoir une ligne comme celle-ci: return lhs.id> rhs.id? -1: .. etc
user2808054

La déclaration de retour de comparaison peut être mieux écrite commeInteger.compare(rhs.customInt, lhs.customInt);
LordKiz

92

Utilisez la méthode util de la classe java.util.Collections , c.-à-d.

Collections.sort(list)

En fait, si vous souhaitez trier un objet personnalisé, vous pouvez utiliser

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

voir les collections api


90

Pour votre exemple, cela fera la magie de Java 8

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

Mais si vous souhaitez trier par certains des champs de l'objet que vous triez, vous pouvez le faire facilement en:

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

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


Où se situe la méthode de «comparaison»?
lippo

1
vous devez importer: import statique java.util.Comparator.comparing;
krmanish007

1
Il est disponible avec Java 1.7?
lippo

5
Non, cela fait partie du flux et de l'interface fonctionnelle, qui fait partie de Java 8
krmanish007

1
Vous avez raison @AjahnCharles. Ils ont supprimé l'argument zéro, j'ai donc mis à jour ma réponse maintenant.
krmanish007

54

En utilisant lambdas (Java8) et en le dépouillant de la syntaxe la plus simple (la JVM en déduira beaucoup dans ce cas), vous obtenez:

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

Une version plus verbeuse:

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

Collections.sort(testList, comp);

L'utilisation d'un lambda est possible car l'interface du comparateur n'a qu'une seule méthode à implémenter, de sorte que la machine virtuelle peut déduire quelle méthode implémente. Étant donné que les types de paramètres peuvent être déduits, ils n'ont pas besoin d'être indiqués (c'est- (a, b)à- dire au lieu de (Double a, Double b). Et puisque le corps lambda n'a qu'une seule ligne, et que la méthode devrait renvoyer une valeur, le returnest inféré et les accolades ne sont pas nécessaires.


C'est cool, merci! Celui-ci est un peu plus compact: Collections.sort (testList, Comparator.reverseOrder ());
kavics

Encore plus compact: testList.sort (Comparator.reverseOrder ());
jonasespelita

29

Avec Java8, il existe une méthode de tri par défaut sur l'interface List qui vous permettra de trier la collection si vous fournissez un comparateur. Vous pouvez facilement trier l'exemple de la question comme suit:

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

Remarque: les arguments dans le lambda sont échangés lorsqu'ils sont transmis à Double.compare pour garantir que le tri est décroissant


Pour moi, c'est la meilleure réponse car elle fonctionne également pour le tri à l'aide d'objets ... exemple locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas

26

Vous pouvez utiliser Collections.sort(list)pour trier listsi votre listcontient des Comparableéléments. Sinon, je vous recommanderais d'implémenter cette interface comme ici:

public class Circle implements Comparable<Circle> {}

et bien sûr fournir votre propre réalisation de compareTométhode comme ici:

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

Et puis vous pouvez à nouveau utiliser Colection.sort(list)comme maintenant la liste contient des objets de type comparable et peut être triée. L'ordre dépend de la compareTométhode. Consultez ce https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html pour des informations plus détaillées.


11

Collections.sortvous permet de passer une instance de a Comparatorqui définit la logique de tri. Ainsi, au lieu de trier la liste dans l'ordre naturel puis de l'inverser, on peut simplement passer Collections.reverseOrder()à sortpour trier la liste dans l'ordre inverse:

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

Comme mentionné par @ Marco13, en plus d'être plus idiomatique (et peut-être plus efficace), l'utilisation du comparateur d'ordre inverse garantit que le tri est stable (ce qui signifie que l'ordre des éléments ne sera pas modifié lorsqu'ils sont égaux selon le comparateur, alors que l'inversion changera l'ordre)


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;

    }
}

semble être thas est Collections.synchronizedList nous aide
vitalinvent

7

Voici un petit cheatsheet qui couvre des cas typiques:

// 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 vous utilisez Java SE 8, cela peut être utile.

//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
Il y a aussi Collections.reverseOrder()sans aucun argument, ce qui rend votre implémentation de compareDoublesuperflu (c'est équivalent à l'ordre naturel de Doubles). La réponse ici devrait êtreCollections.sort(testList, Collections.reverseOrder());
Matt

5

| * | Tri d'une liste:

import java.util.Collections;

| => Ordre de tri asc:

Collections.sort(NamAryVar);

| => Trier l'ordre Dsc:

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

| * | Inversez l'ordre de la liste:

Collections.reverse(NamAryVar);

4

Vous pouvez faire comme ça:

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

La collection a un comparateur par défaut qui peut vous aider avec cela.

De plus, si vous souhaitez utiliser certaines nouvelles fonctionnalités de Java 8, vous pouvez faire comme ça:

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

3

Par exemple, j'ai une classe 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

Dans JAVA 8, c'est beaucoup plus facile maintenant.

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]

- Pour une utilisation inverse,

.sorted(Comparator.reverseOrder())

3

Vous pouvez utiliser comme ça

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

1

Avec Eclipse Collections, vous pouvez créer une double liste primitive, la trier puis l'inverser pour la mettre dans l'ordre décroissant. Cette approche éviterait de boxer les doubles.

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 vous voulez un List<Double>, alors ce qui suit fonctionnerait.

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 vous souhaitez conserver le type sous ArrayList<Double>, vous pouvez initialiser et trier la liste à l'aide de la ArrayListIterateclasse utilitaire comme suit:

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

Remarque: je suis un committer pour les collections Eclipse .


1

La ligne suivante devrait faire l'épaisseur

testList.sort(Collections.reverseOrder());
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.