Wie sortiere ich eine ArrayList?

352

Ich habe eine Liste von Doubles in Java und möchte ArrayList in absteigender Reihenfolge sortieren.

Die EingabearrayList lautet wie folgt:

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

Die Ausgabe sollte so sein

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
quelle

Antworten:

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

Das wird machen was du willst. Denken Sie jedoch daran, zu importieren Collections!

Hier ist die Dokumentation fürCollections .

tckmn
quelle
53
Vielleicht ist es erwähnenswert, dass Sie Ihre eigenen definieren können Comparator:)
Polygnome
1
@Polygnome Das OP sortiert nur Doubles.
Tckmn
3
Ja, aber Sie können sie je nach Anwendungsfall auf verschiedene Arten sortieren. Manchmal möchten Sie sie vielleicht nach Abstand bis 0 sortieren. Ich weiß nicht einmal, wie die Laufzeitmerkmale von reverseaussehen, aber das Sortieren absteigend kann tatsächlich schneller sein als das Sortieren aufsteigend und dann rückwärts. Darüber hinaus würde die Verwendung einer List-Implementierung, die Comparatorals Konstruktorargument unterstützt (und somit unveränderlich bleibt), sicherstellen, dass die Liste jederzeit sortiert ist.
Polygnome
4
@ Ayesha Ja, Collections.sortverwendet compareTohinter den Kulissen.
Tckmn
45
Man sollte eigentlich verwenden Collections.sort(list, Collections.reverseOrder());. Abgesehen davon, dass die Verwendung des Komparators in umgekehrter Reihenfolge idiomatischer (und möglicherweise effizienter) ist, wird sichergestellt, dass die Sortierung stabil ist (was bedeutet, dass die Reihenfolge der Elemente nicht geändert wird, wenn sie gemäß dem Komparator gleich sind, wohingegen die Umkehrung die Reihenfolge ändert ).
Marco13
134

Absteigend:

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
quelle
1
Was soll ich tun , wenn CustomData heißt , List<AnotherModel>das AnotherModelhat idund ich zu sortieren will durch id? Und ich greife einfach auf das CustomData Modell in meiner Klasse zu.
Dr. Jacky
2
Sie würden einfach die CustomData-Klasse durch AnotherModel ersetzen und eine Zeile wie diese haben: return lhs.id> rhs.id? -1: .. etc
user2808054
Die Vergleichserklärung kann besser geschrieben werden alsInteger.compare(rhs.customInt, lhs.customInt);
LordKiz
92

Verwenden Sie die util-Methode der Klasse java.util.Collections , d. H.

Collections.sort(list)

Wenn Sie ein benutzerdefiniertes Objekt sortieren möchten, können Sie es sogar verwenden

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

siehe Sammlungen api

M Sach
quelle
90

In Ihrem Beispiel zaubert dies in Java 8

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

Wenn Sie jedoch nach einigen Feldern des zu sortierenden Objekts sortieren möchten, können Sie dies ganz einfach tun, indem Sie:

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

oder

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

oder

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

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

krmanish007
quelle
Wo befindet sich die Vergleichsmethode?
Lippo
1
Sie müssen importieren: statische java.util.Comparator.comparing importieren;
krmanish007
1
Es ist mit Java 1.7 verfügbar?
Lippo
5
Nein, dies ist ein Teil des Streams und der funktionalen Schnittstelle, die alle Teil von Java 8
krmanish007
1
Sie haben Recht @AjahnCharles. Sie haben Zero-Arg entfernt, daher habe ich meine Antwort jetzt aktualisiert.
krmanish007
54

Wenn Sie Lambdas (Java8) verwenden und es auf die kleinste Syntax reduzieren (die JVM wird in diesem Fall viel ableiten ), erhalten Sie:

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

Eine ausführlichere Version:

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

Collections.sort(testList, comp);

Die Verwendung eines Lambda ist möglich, da die Comparator-Schnittstelle nur eine einzige Methode zu implementieren hat, sodass die VM ableiten kann, welche Methode implementiert wird. Da die Typen der Parameter abgeleitet werden können, müssen sie nicht angegeben werden (dh (a, b)statt (Double a, Double b). Und da der Lambda-Körper nur eine einzige Zeile hat und von der Methode erwartet wird, dass sie einen Wert returnzurückgibt, werden die und die geschweiften Klammern zurückgegeben sind nicht notwendig.

Cyrus
quelle
Das ist cool, danke! Dieser ist etwas kompakter: Collections.sort (testList, Comparator.reverseOrder ());
Kavics
Noch kompakter: testList.sort (Comparator.reverseOrder ());
Jonasespelita
29

Mit Java8 gibt es eine Standardsortiermethode auf der List-Oberfläche, mit der Sie die Sammlung sortieren können, wenn Sie einen Komparator bereitstellen. Sie können das Beispiel in der Frage einfach wie folgt sortieren:

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

Hinweis: Die Argumente im Lambda werden ausgetauscht, wenn sie an Double.compare übergeben werden, um sicherzustellen, dass die Sortierung absteigend ist

Robjwilkins
quelle
Für mich ist dies die beste Antwort, da es auch zum Sortieren nach Objekten funktioniert ... Beispiel locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas
26

Sie können verwenden Collections.sort(list)zu sortieren , listwenn Ihr listenthält ComparableElemente. Ansonsten würde ich Ihnen empfehlen, diese Schnittstelle wie hier zu implementieren:

public class Circle implements Comparable<Circle> {}

und natürlich bieten Sie Ihre eigene Realisierung der compareToMethode wie hier:

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

Und dann können Sie wieder verwenden, Colection.sort(list)da jetzt die Liste Objekte vom Typ Vergleichbar enthält und sortiert werden kann. Die Reihenfolge hängt von der compareToMethode ab. Weitere Informationen finden Sie unter https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html .

Yuriy
quelle
11

Collections.sortMit dieser Option können Sie eine Instanz von a übergeben, Comparatordie die Sortierlogik definiert. Anstatt die Liste in natürlicher Reihenfolge zu sortieren und dann umzukehren, kann man einfach zu übergeben Collections.reverseOrder(), sortum die Liste in umgekehrter Reihenfolge zu sortieren:

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

Wie von @ Marco13 erwähnt, ist die Verwendung des Komparators in umgekehrter Reihenfolge nicht nur idiomatischer (und möglicherweise effizienter), sondern stellt auch sicher, dass die Sortierung stabil ist (was bedeutet, dass die Reihenfolge der Elemente nicht geändert wird, wenn sie gemäß dem Komparator gleich sind. wohingegen das Umkehren die Reihenfolge ändert)

Matt
quelle
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
quelle
scheint zu sein, dass Collections.synchronizedList uns hilft
vitalinvent
7

Hier ist ein kurzes Cheatsheet, das typische Fälle abdeckt:

// 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
quelle
5

Wenn Sie Java SE 8 verwenden, kann dies hilfreich sein.

//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
quelle
6
Es gibt auch Collections.reverseOrder()keine Argumente, was Ihre Implementierung compareDoubleüberflüssig macht (es entspricht der natürlichen Reihenfolge von Doubles). Die Antwort hier sollte seinCollections.sort(testList, Collections.reverseOrder());
Matt
5

| * | Eine Liste sortieren:

import java.util.Collections;

| => Sort Asc Order:

Collections.sort(NamAryVar);

| => Dsc-Reihenfolge sortieren:

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

| * | Kehren Sie die Reihenfolge der Liste um:

Collections.reverse(NamAryVar);
Sujay UN
quelle
4

Sie können dies tun:

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

Collection verfügt über einen Standardkomparator, der Ihnen dabei helfen kann.

Wenn Sie einige neue Java 8-Funktionen verwenden möchten, können Sie Folgendes tun:

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

Zum Beispiel habe ich eine Klasse Person: String name, int age ==> Konstruktor new Person (Name, Alter)

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
quelle
if you want to short by name->if you want to sort by name
Linrongbin
3

In JAVA 8 ist es jetzt viel einfacher.

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]

- Für den umgekehrten Gebrauch verwenden

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

Sie können so verwenden

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

Mit Eclipse Collections können Sie eine primitive Doppelliste erstellen, sortieren und dann umkehren, um sie in absteigender Reihenfolge anzuordnen. Dieser Ansatz würde das Boxen der Doppel vermeiden.

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

Wenn Sie eine möchten List<Double>, funktioniert Folgendes.

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

Wenn Sie den Typ beibehalten möchten ArrayList<Double>, können Sie die Liste mithilfe der ArrayListIterateDienstprogrammklasse wie folgt initialisieren und sortieren :

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

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen .

Donald Raab
quelle
1

Die folgende Zeile sollte die Dicke tun

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