Jak posortować ArrayList?

351

Mam listę podwójnych w Javie i chcę sortować ArrayList w kolejności malejącej.

Input ArrayList jest jak poniżej:

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

Wyjście powinno wyglądać tak

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
źródło

Odpowiedzi:

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

To zrobi, co chcesz. Pamiętaj jednak, aby zaimportować Collections!

Oto dokumentacja dlaCollections .

tckmn
źródło
53
Może warto wspomnieć, że możesz zdefiniować własne Comparator:)
Polygnome 27.04.13
1
@Polygnome OP sortuje tylko Doubles.
tckmn 27.04.13
3
Tak, ale można je sortować na różne sposoby, w zależności od przypadku użycia. Czasami możesz chcieć posortować je według odległości do 0. Nie wiem nawet o charakterystykach uruchomieniowych reverse, ale sortowanie malejące może być w rzeczywistości szybsze niż sortowanie rosnące, a następnie cofanie. Co więcej, użycie implementacji List, która obsługuje Comparatorjako argument konstruktora (utrzymując ją niezmienną), zapewniłoby sortowanie listy przez cały czas.
Polygnome 27.04.13
4
@Ayesha Tak, Collections.sortużywa compareToza kulisami.
tckmn
45
Trzeba właściwie użyć Collections.sort(list, Collections.reverseOrder());. Oprócz bycia bardziej idiomatycznym (i być może bardziej wydajnym), użycie komparatora w odwrotnej kolejności zapewnia, że ​​sortowanie jest stabilne (co oznacza, że ​​kolejność elementów nie zostanie zmieniona, gdy będą one równe w zależności od komparatora, natomiast odwrócenie zmieni kolejność ).
Marco13
133

Malejąco:

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
źródło
1
Co powinienem zrobić, jeśli CustomData to, List<AnotherModel>co AnotherModelma idi chcę posortować id? I po prostu mam dostęp do CustomData modelu w mojej klasie.
Dr.jacky
2
Po prostu zamieniłbyś klasę CustomData na AnotherModel i miałbyś taką linię: return lhs.id> rhs.id? -1: .. etc
user2808054 12.01.18
Porównującą deklarację zwrotu można lepiej zapisać jakoInteger.compare(rhs.customInt, lhs.customInt);
LordKiz,
92

Użyj metody util klasy java.util.Collections , tj

Collections.sort(list)

W rzeczywistości, jeśli chcesz posortować niestandardowy obiekt, którego możesz użyć

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

zobacz kolekcje API

M. Sach
źródło
90

Na przykład zrobi to magię w Javie 8

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

Ale jeśli chcesz posortować według niektórych pól sortowanego obiektu, możesz to łatwo zrobić:

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

lub

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

lub

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

Źródła: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

krmanish007
źródło
Gdzie znajduje się metoda „porównywania”?
lippo
1
musisz zaimportować: import static java.util.Comparator.comparing;
krmanish007
1
Jest dostępny z Javą 1.7?
lippo
5
Nie, jest to część strumienia i funkcjonalnego interfejsu, który jest częścią Java 8
krmanish007
1
Masz rację @AjahnCharles. Usunęli zero-arg, więc zaktualizowałem teraz swoją odpowiedź.
krmanish007,
54

Używając lambdas (Java8) i sprowadzając go do najprostszej składni (JVM będzie wnioskować dużo w tym przypadku), otrzymujesz:

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

Bardziej pełna wersja:

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

Collections.sort(testList, comp);

Zastosowanie lambda jest możliwe, ponieważ interfejs komparatora ma tylko jedną metodę do zaimplementowania, więc maszyna wirtualna może stwierdzić, która metoda jest implementowana. Ponieważ typy parametrów można wywnioskować, nie trzeba ich podawać (tj. (a, b)Zamiast (Double a, Double b). A ponieważ ciało lambda ma tylko jedną linię, a metoda powinna zwrócić wartość, returnwnioskuje i nawiasy klamrowe nie są konieczne.

cyrus
źródło
To jest fajne, dzięki! Ten jest nieco bardziej kompaktowy: Collections.sort (testList, Comparator.reverseOrder ());
kavics
Jeszcze bardziej kompaktowy: testList.sort (Comparator.reverseOrder ());
jonasespelita
29

W Javie 8 istnieje domyślna metoda sortowania w interfejsie listy, która pozwoli ci posortować kolekcję, jeśli podasz komparator. Możesz łatwo posortować przykład w pytaniu w następujący sposób:

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

Uwaga: argumenty w lambda są zamieniane po przekazaniu do Double.compare, aby upewnić się, że sortowanie jest malejące

robjwilkins
źródło
Dla mnie jest to najlepsza odpowiedź, ponieważ działa także w przypadku sortowania przy użyciu obiektów ... przykład locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas
26

Możesz użyć Collections.sort(list)do sortowania, listjeśli listzawiera Comparableelementy. W przeciwnym razie polecam zaimplementować ten interfejs jak tutaj:

public class Circle implements Comparable<Circle> {}

i oczywiście zapewnij własną realizację compareTometody jak tutaj:

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

Następnie możesz ponownie użyć, Colection.sort(list)ponieważ teraz lista zawiera obiekty typu Porównywalne i można je sortować. Zamówienie zależy od compareTometody. Sprawdź to https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html, aby uzyskać bardziej szczegółowe informacje.

Jurij
źródło
11

Collections.sortpozwala przekazać instancję, Comparatorktóra definiuje logikę sortowania. Zamiast więc sortować listę w naturalnej kolejności, a następnie ją odwracać, można po prostu przejść Collections.reverseOrder()do sort, aby posortować listę w odwrotnej kolejności:

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

Jak wspomniał @ Marco13, oprócz bycia bardziej idiomatycznym (i być może bardziej wydajnym), użycie komparatora odwrotnej kolejności zapewnia, że ​​sortowanie jest stabilne (co oznacza, że ​​kolejność elementów nie zostanie zmieniona, gdy będą one równe według komparatora, podczas gdy cofanie zmieni kolejność)

Matt
źródło
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
źródło
wygląda na to, że pomaga nam Kolekcja.synchronizedList
vitalinvent
7

Oto krótki ściągawka, która obejmuje typowe przypadki:

// 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
źródło
5

jeśli używasz Java SE 8, może to być pomocne.

//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
źródło
6
Nie ma też Collections.reverseOrder()żadnych argumentów, co czyni compareDoublezbędną implementację (jest to równoważne naturalnemu uporządkowaniu Doubles). Odpowiedź powinna być następującaCollections.sort(testList, Collections.reverseOrder());
Matt
5

| * | Sortowanie listy:

import java.util.Collections;

| => Sortuj kolejność asc:

Collections.sort(NamAryVar);

| => Sortuj porządek Dsc:

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

| * | Odwróć kolejność na liście:

Collections.reverse(NamAryVar);
Sujay ONZ
źródło
4

Możesz to zrobić w następujący sposób:

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

Kolekcja ma domyślny komparator, który może ci w tym pomóc.

Ponadto, jeśli chcesz korzystać z nowych funkcji Java 8, możesz to zrobić w następujący sposób:

List<String> yourList = new ArrayList<String>();
yourList = yourList.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
Thiago
źródło
3

Na przykład mam klasę Osoba: Nazwa ciągu, int wiek ==> Konstruktor nowa osoba (imię, wiek)

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
źródło
if you want to short by name->if you want to sort by name
linrongbin
3

W JAVA 8 jest teraz bardzo łatwo.

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]

- Do odwrotnego użycia tego

.sorted(Comparator.reverseOrder())
Appesh
źródło
3

Możesz użyć w ten sposób

ArrayList<Group> groupList = new ArrayList<>();
Collections.sort(groupList, Collections.reverseOrder());
Collections.reverse(groupList);
manikant gautam
źródło
1

Dzięki Eclipse Collections możesz stworzyć prymitywną podwójną listę, posortować ją, a następnie odwrócić, aby uporządkować w kolejności malejącej. Takie podejście pozwoliłoby uniknąć boksowania podwójnych.

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

Jeśli chcesz List<Double>, to działałyby następujące.

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

Jeśli chcesz zachować typ as ArrayList<Double>, możesz zainicjować i posortować listę za pomocą ArrayListIterateklasy narzędziowej w następujący sposób:

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

Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse .

Donald Raab
źródło
1

Poniższa linia powinna zrobić gruby

testList.sort(Collections.reverseOrder());
Ivan Kovtun
źródło