Làm thế nào để sắp xếp một ArrayList?


352

Tôi có một Danh sách nhân đôi trong java và tôi muốn sắp xếp ArrayList theo thứ tự giảm dần.

ArrayList đầu vào như sau:

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

Đặt ra nên như thế này

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

Câu trả lời:


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

Điều đó sẽ làm những gì bạn muốn. Nhớ nhập Collectionsdù!

Đây là tài liệu choCollections .


53
Có lẽ điều đáng nói là bạn có thể tự xác định Comparator:)
Polygnome

1
@Polygnome OP chỉ sắp xếp Doubles.
tckmn

3
Có, nhưng bạn có thể sắp xếp chúng theo nhiều cách khác nhau, tùy thuộc vào trường hợp sử dụng. Đôi khi bạn có thể muốn sắp xếp chúng theo khoảng cách đến 0. Tôi thậm chí không biết về các đặc điểm thời gian chạy của reverse, nhưng sắp xếp giảm dần thực sự có thể nhanh hơn sau đó sắp xếp tăng dần và sau đó đảo ngược. Ngoài ra, sử dụng triển khai Danh sách hỗ trợ Comparatorlàm đối số hàm tạo (do đó giữ cho nó bất biến) sẽ đảm bảo danh sách được sắp xếp mọi lúc.
Polygnome

4
@Ayesha Vâng, Collections.sortsử dụng compareTođằng sau hậu trường.
tckmn

45
Một người nên thực sự sử dụng Collections.sort(list, Collections.reverseOrder());. Ngoài việc thành ngữ hơn (và có thể hiệu quả hơn), sử dụng bộ so sánh thứ tự ngược lại đảm bảo rằng loại sắp xếp ổn định (có nghĩa là thứ tự các phần tử sẽ không bị thay đổi khi chúng bằng với bộ so sánh, trong khi đảo ngược sẽ thay đổi thứ tự ).
Marco13

134

Giảm dần:

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
Tôi nên làm gì nếu CustomData List<AnotherModel>AnotherModelidvà tôi muốn sắp xếp theo id? Và tôi chỉ truy cập vào CustomData mô hình trong lớp học của tôi.
Dr.jacky

2
Bạn chỉ cần thay thế lớp CustomData bằng AnotherModel và có một dòng như thế này: return lhs.id> rhs.id? -1: .. vv
user2808054

Tuyên bố hoàn trả so sánh có thể được viết tốt hơn nhưInteger.compare(rhs.customInt, lhs.customInt);
LordKiz

92

Sử dụng phương thức produc của lớp java.util.Collections , tức là

Collections.sort(list)

Trong thực tế, nếu bạn muốn sắp xếp đối tượng tùy chỉnh, bạn có thể sử dụng

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

xem bộ sưu tập api


90

Ví dụ của bạn, điều này sẽ làm nên điều kỳ diệu trong Java 8

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

Nhưng nếu bạn muốn sắp xếp theo một số trường của đối tượng bạn đang sắp xếp, bạn có thể thực hiện dễ dàng bằng cách:

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

hoặc là

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

hoặc là

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

Nguồn: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html


Phương pháp 'so sánh' nằm ở đâu?
lippo

1
bạn cần nhập: nhập java.util.Comparator.compared tĩnh;
krmanish007

1
Nó có sẵn với Java 1.7 không?
lippo

5
Không, đây là một phần của luồng và giao diện chức năng, là một phần của Java 8
krmanish007

1
Bạn nói đúng @AjahnCharles. Họ đã loại bỏ zero-arg, vì vậy tôi đã cập nhật câu trả lời của mình ngay bây giờ.
krmanish007

54

Sử dụng lambdas (Java8) và tước nó xuống hàng loạt cú pháp (JVM sẽ suy ra rất nhiều trong trường hợp này), bạn nhận được:

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

Một phiên bản dài dòng hơn:

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

Collections.sort(testList, comp);

Có thể sử dụng lambda vì giao diện Trình so sánh chỉ có một phương thức duy nhất để thực hiện, do đó VM có thể suy ra phương thức nào đang thực hiện. Vì các loại thông số có thể được suy ra, nên chúng không cần phải được nêu ( (a, b)thay vì (Double a, Double b). Và vì cơ thể lambda chỉ có một dòng duy nhất và phương thức dự kiến ​​sẽ trả về một giá trị, nên returnđược suy ra và niềng răng không cần thiết


Thật tuyệt, cảm ơn! Cái này nhỏ gọn hơn một chút: Collections.sort (testList, so sánh.reverseOrder ());
kavics

Thậm chí gọn hơn: testList.sort (so sánh.reverseOrder ());
jonasespelita

29

Với Java8, có một phương thức sắp xếp mặc định trên giao diện Danh sách sẽ cho phép bạn sắp xếp bộ sưu tập nếu bạn cung cấp Trình so sánh. Bạn có thể dễ dàng sắp xếp ví dụ trong câu hỏi như sau:

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

Lưu ý: các đối số trong lambda được hoán đổi khi được truyền vào Double.compare để đảm bảo sắp xếp giảm dần


Đối với tôi đây là câu trả lời tốt nhất vì nó cũng hoạt động để sắp xếp bằng cách sử dụng các đối tượng ... ví dụ locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas

26

Bạn có thể sử dụng Collections.sort(list)để sắp xếp listnếu listcó chứa Comparablecác yếu tố. Nếu không, tôi khuyên bạn nên thực hiện giao diện đó như ở đây:

public class Circle implements Comparable<Circle> {}

và tất nhiên cung cấp nhận thức của riêng bạn về compareTophương pháp như ở đây:

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

Và sau đó bạn có thể sử dụng lại Colection.sort(list)như danh sách bây giờ chứa các đối tượng thuộc loại So sánh và có thể được sắp xếp. Thứ tự phụ thuộc vào compareTophương pháp. Kiểm tra https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html này để biết thêm thông tin chi tiết.


11

Collections.sortcho phép bạn vượt qua một thể hiện của một Comparatorđịnh nghĩa logic sắp xếp. Vì vậy, thay vì sắp xếp danh sách theo thứ tự nhiên và sau đó đảo ngược nó, người ta có thể dễ dàng vượt qua Collections.reverseOrder()để sortđể sắp xếp danh sách theo thứ tự ngược lại:

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

Như được đề cập bởi @ Marco13, ngoài việc thành ngữ hơn (và có thể hiệu quả hơn), sử dụng bộ so sánh thứ tự ngược lại đảm bảo rằng loại sắp xếp ổn định (có nghĩa là thứ tự các yếu tố sẽ không bị thay đổi khi chúng bằng với bộ so sánh, trong khi đảo ngược sẽ thay đổi thứ tự)


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;

    }
}

Dường như đó là Bộ sưu tập. Bộ đồng bộ hóa giúp chúng tôi
Vitalinvent

7

Dưới đây là một chiếc áo ngắn bao gồm các trường hợp điển hình:

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

nếu bạn đang sử dụng Java SE 8, thì điều này có thể hữu ích.

//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
Cũng Collections.reverseOrder()không có bất kỳ đối số nào, điều này làm cho việc triển khai của bạn trở nên compareDoublethừa thãi (nó tương đương với thứ tự tự nhiên của Doubles). Câu trả lời ở đây nên làCollections.sort(testList, Collections.reverseOrder());
Matt

5

| * | Sắp xếp danh sách:

import java.util.Collections;

| => Sắp xếp thứ tự Asc:

Collections.sort(NamAryVar);

| => Sắp xếp thứ tự Dsc:

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

| * | Đảo ngược thứ tự của Danh sách:

Collections.reverse(NamAryVar);

4

Bạn có thể làm như thế này:

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

Bộ sưu tập có Bộ so sánh mặc định có thể giúp bạn điều đó.

Ngoài ra, nếu bạn muốn sử dụng một số tính năng mới của Java 8, bạn có thể làm như vậy:

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

3

Ví dụ: tôi có một lớp Người: Tên chuỗi, int age ==> Người xây dựng Người mới (tên, tuổi)

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

Trong JAVA 8 bây giờ rất dễ dàng.

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]

- Để sử dụng ngược lại

.sorted(Comparator.reverseOrder())

3

Bạn có thể sử dụng như thế

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

1

Với Bộ sưu tập Eclipse, bạn có thể tạo một danh sách kép nguyên thủy, sắp xếp nó và sau đó đảo ngược nó để đặt nó theo thứ tự giảm dần. Cách tiếp cận này sẽ tránh đấm bốc đôi.

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

Nếu bạn muốn một List<Double>, sau đó sẽ làm việc.

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

Nếu bạn muốn giữ kiểu như ArrayList<Double>, bạn có thể khởi tạo và sắp xếp danh sách bằng cách sử dụng ArrayListIteratelớp tiện ích như sau:

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

Lưu ý: Tôi là người đi làm cho Bộ sưu tập Eclipse .


1

Các dòng sau nên làm dày

testList.sort(Collections.reverseOrder());
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.