Bagaimana cara mengurutkan ArrayList?

352

Saya memiliki Daftar ganda di java dan saya ingin mengurutkan ArrayList dalam urutan menurun.

Input ArrayList adalah sebagai berikut:

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

Put out harus seperti ini

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
sumber

Jawaban:

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

Itu akan melakukan apa yang Anda inginkan. Ingatlah untuk mengimpor Collections!

Ini adalah dokumentasi untukCollections .

tckmn
sumber
53
Mungkin perlu disebutkan bahwa Anda dapat menentukan sendiri Comparator:)
Polygnome
1
@Polygnome OP hanya menyortir Doubles.
tckmn
3
Ya, tetapi Anda bisa mengurutkannya dengan berbagai cara, tergantung pada use case. Kadang-kadang Anda mungkin ingin mengurutkannya dengan jarak ke 0. Saya bahkan tidak tahu tentang karakteristik runtime reverse, tetapi menyortir turun sebenarnya bisa lebih cepat kemudian menyortir naik dan kemudian membalikkan. Selain itu, menggunakan implementasi Daftar yang mendukung Comparatorsebagai argumen konstruktor (sehingga menjaganya tidak berubah) akan memastikan daftar diurutkan setiap saat.
Polygnome
4
@ Ayesha Ya, Collections.sortgunakan di compareTobelakang layar.
tckmn
45
Seseorang harus benar-benar menggunakannya Collections.sort(list, Collections.reverseOrder());. Selain lebih idiomatis (dan mungkin lebih efisien), menggunakan pembanding urutan terbalik memastikan bahwa jenisnya stabil (artinya urutan elemen tidak akan berubah ketika mereka sama menurut pembanding, sedangkan membalikkan akan mengubah urutan ).
Marco13
134

Menurun:

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
sumber
1
Apa yang harus saya lakukan jika CustomData yaitu List<AnotherModel>yang AnotherModelmemiliki iddan saya ingin mengurutkan berdasarkan id? Dan saya hanya mengakses CustomData model di kelas saya.
Dr.jacky
2
Anda baru saja mengganti kelas CustomData dengan AnotherModel dan memiliki garis seperti ini: return lhs.id> rhs.id? -1: .. etc
user2808054
Pernyataan pengembalian perbandingan bisa lebih baik ditulis sebagaiInteger.compare(rhs.customInt, lhs.customInt);
LordKiz
92

Gunakan metode util dari kelas java.util.Collections , yaitu

Collections.sort(list)

Bahkan, jika Anda ingin mengurutkan objek khusus yang dapat Anda gunakan

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

lihat koleksi api

M Sach
sumber
90

Sebagai contoh Anda, ini akan melakukan keajaiban di Java 8

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

Tetapi jika Anda ingin mengurutkan berdasarkan beberapa bidang objek yang Anda sortir, Anda dapat melakukannya dengan mudah dengan:

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

atau

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

atau

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

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

krmanish007
sumber
Di mana letak metode 'pembanding'?
Lippo
1
Anda perlu mengimpor: import java.util.Comparator.comparing statis;
krmanish007
1
Ini tersedia dengan Java 1.7?
lippo
5
Tidak, ini adalah bagian dari aliran dan antarmuka fungsional, yang semuanya adalah bagian dari Java 8
krmanish007
1
Anda benar @AjahnCharles. Mereka telah menghapus zero-arg, jadi saya telah memperbarui jawaban saya sekarang.
krmanish007
54

Menggunakan lambdas (Java8), dan melepasnya ke sintaks yang paling bawah (JVM akan menyimpulkan banyak dalam hal ini), Anda mendapatkan:

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

Versi yang lebih verbose:

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

Collections.sort(testList, comp);

Penggunaan lambda dimungkinkan karena antarmuka Comparator hanya memiliki satu metode untuk diterapkan, sehingga VM dapat menyimpulkan metode mana yang diterapkan. Karena jenis params dapat disimpulkan, mereka tidak perlu dinyatakan (yaitu (a, b)bukannya (Double a, Double b). Dan karena tubuh lambda hanya memiliki satu baris, dan metode ini diharapkan untuk mengembalikan nilai, maka returndisimpulkan dan kawat gigi tidak perlu.

cyrus
sumber
Ini keren, terima kasih! Yang ini sedikit lebih kompak: Collections.sort (testList, Comparator.reverseOrder ());
kavics
Yang lebih ringkas: testList.sort (Comparator.reverseOrder ());
jonasespelita
29

Dengan Java8 ada metode pengurutan default pada antarmuka Daftar yang akan memungkinkan Anda untuk mengurutkan koleksi jika Anda menyediakan Pembanding. Anda dapat dengan mudah mengurutkan contoh dalam pertanyaan sebagai berikut:

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

Catatan: argumen dalam lambda ditukar ketika diteruskan ke Double.compare untuk memastikan jenisnya menurun

robjwilkins
sumber
Bagi saya ini adalah jawaban terbaik karena ini juga berfungsi untuk menyortir menggunakan objek ... contoh locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas
26

Anda dapat menggunakan Collections.sort(list)untuk mengurutkan listjika Anda listmengandung Comparableelemen. Kalau tidak, saya akan merekomendasikan Anda untuk mengimplementasikan antarmuka itu seperti di sini:

public class Circle implements Comparable<Circle> {}

dan tentu saja memberikan realisasi compareTometode Anda sendiri seperti di sini:

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

Dan kemudian Anda dapat kembali menggunakan Colection.sort(list)karena sekarang daftar berisi objek dengan tipe Sebanding dan dapat diurutkan. Pesanan tergantung pada compareTometode. Periksa https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html ini untuk informasi lebih rinci.

Yuriy
sumber
11

Collections.sortmemungkinkan Anda untuk melewati contoh Comparatoryang mendefinisikan logika penyortiran Jadi, bukannya menyortir daftar dalam urutan alami dan kemudian membalikkan itu, satu hanya dapat lulus Collections.reverseOrder()untuk sortuntuk menyortir daftar dalam urutan terbalik:

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

Seperti disebutkan oleh @ Marco13, selain lebih idiomatis (dan mungkin lebih efisien), menggunakan pembanding urutan terbalik memastikan bahwa pengurutannya stabil (artinya urutan elemen tidak akan berubah ketika mereka sama menurut pembanding, sedangkan membalikkan akan mengubah urutan)

Mat
sumber
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
sumber
tampaknya ini adalah Collections.synchronizedList membantu kita
vitalinvent
7

Berikut ini adalah lembar contekan pendek yang mencakup beberapa kasus umum:

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

jika Anda menggunakan Java SE 8, maka ini mungkin bisa membantu.

//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
sumber
6
Ada juga Collections.reverseOrder()tanpa argumen, yang membuat implementasi Anda compareDoubleberlebihan (itu setara dengan pemesanan alami Doubles). Jawabannya di sini adalahCollections.sort(testList, Collections.reverseOrder());
Mat
5

| * | Menyortir Daftar:

import java.util.Collections;

| => Urutkan Urutan Pesanan:

Collections.sort(NamAryVar);

| => Urutkan Urutan Dsc:

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

| * | Membalik urutan Daftar:

Collections.reverse(NamAryVar);
Sujay UN
sumber
4

Anda bisa melakukan ini:

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

Koleksi memiliki Pembanding default yang dapat membantu Anda dengan itu.

Selain itu, jika Anda ingin menggunakan beberapa fitur Java 8 baru, Anda dapat melakukannya seperti itu:

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

Misalnya saya punya Person kelas: Nama string, int age ==> Buat Person baru (nama, umur)

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

Di JAWA 8 sekarang jauh lebih mudah.

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]

- Untuk kebalikannya gunakan ini

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

Anda bisa menggunakan seperti itu

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

Dengan Eclipse Collections, Anda dapat membuat daftar ganda primitif, mengurutkannya, lalu membalikkannya untuk meletakkannya secara berurutan. Pendekatan ini akan menghindari tinju ganda.

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

Jika Anda menginginkan List<Double>, maka yang berikut ini akan berfungsi.

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

Jika Anda ingin mempertahankan tipenya ArrayList<Double>, Anda dapat menginisialisasi dan mengurutkan daftar menggunakan ArrayListIteratekelas utilitas sebagai berikut:

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

Catatan: Saya pengendara untuk Eclipse Collections .

Donald Raab
sumber
1

Baris berikut harus tebal

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