Как отсортировать ArrayList?


353

У меня есть список двойников в Java, и я хочу отсортировать ArrayList в порядке убывания.

Входной ArrayList, как показано ниже:

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

Выход должен быть таким

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

Ответы:


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

Это будет делать то, что вы хотите. Не забудьте импортировать, Collectionsхотя!

Вот документация дляCollections .


53
Может быть, стоит упомянуть, что вы можете определить свой собственный Comparator:)
Polygnome

1
@Polygnome OP только сортировка Doubles.
tckmn

3
Да, но вы можете сортировать их по-разному, в зависимости от варианта использования. Иногда вам может понадобиться отсортировать их по расстоянию до 0. Я даже не знаю о характеристиках времени выполнения reverse, но сортировка по убыванию может быть быстрее, чем сортировка по возрастанию, а затем наоборот. Более того, использование реализации List, которая поддерживает в Comparatorкачестве аргумента конструктора (сохраняя его неизменным), обеспечит постоянную сортировку списка.
Полигном,

4
@Ayesha Да, Collections.sortиспользует compareToза кулисами.
tckmn

45
Надо на самом деле использовать Collections.sort(list, Collections.reverseOrder());. Помимо того, что он более идиоматичен (и, возможно, более эффективен), использование компаратора обратного порядка обеспечивает стабильность сортировки (это означает, что порядок элементов не изменится, если они равны по сравнению с компаратором, тогда как реверсирование изменит порядок ).
Marco13

134

По убыванию:

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
Что делать , если CustomData есть , List<AnotherModel>который AnotherModelимеет , idи я хочу отсортировать по id? И я просто доступ к CustomData модели в моем классе.
Dr.jacky

2
Вы бы просто заменили класс CustomData на AnotherModel и получили бы такую ​​строку: return lhs.id> rhs.id? -1: .. и т.д
user2808054

Оператор сравнения возврата может быть лучше записан какInteger.compare(rhs.customInt, lhs.customInt);
LordKiz

92

Используйте метод util класса java.util.Collections , т.е.

Collections.sort(list)

На самом деле, если вы хотите отсортировать пользовательский объект, вы можете использовать

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

смотреть коллекции API


90

Для вашего примера, это сделает волшебство в Java 8

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

Но если вы хотите отсортировать по некоторым полям сортируемого объекта, вы можете сделать это легко:

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

или

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

или

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

Источники: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html.


Где находится метод сравнения?
Липпо

1
вам нужно импортировать: импортировать статический java.util.Comparator.comparing;
krmanish007

1
Это доступно с Java 1.7?
Липпо

5
Нет, это часть потокового и функционального интерфейса, который является частью Java 8
krmanish007

1
Вы правы @AjahnCharles. Они убрали нулевой аргумент, поэтому я обновил свой ответ сейчас.
krmanish007

54

Используя лямбды (Java8) и сокращая их до минимума синтаксиса ( в этом случае JVM будет многое выводить ), вы получите:

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

Более подробная версия:

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

Collections.sort(testList, comp);

Использование лямбды возможно, потому что интерфейс Comparator имеет только один метод для реализации, поэтому виртуальная машина может определить, какой метод реализует. Поскольку типы параметров могут быть выведены, их указывать не нужно (т. Е. (a, b)Вместо (Double a, Double b). И поскольку лямбда-тело имеет только одну строку, а метод должен возвращать значение, returnвыводится и скобки не нужны


Это круто, спасибо! Это немного более компактно: Collections.sort (testList, Comparator.reverseOrder ());
Kavics

Еще более компактный: testList.sort (Comparator.reverseOrder ());
jonasespelita

29

В Java8 есть метод сортировки по умолчанию в интерфейсе List, который позволит вам сортировать коллекцию, если вы предоставите Comparator. Вы можете легко отсортировать пример в вопросе следующим образом:

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

Примечание: аргументы в лямбда-выражениях меняются местами при передаче в Double.compare, чтобы обеспечить сортировку по убыванию


Для меня это лучший ответ, так как он также работает для сортировки с использованием объектов ... пример locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Anas

26

Вы можете использовать Collections.sort(list)для сортировки, listесли ваши элементы listсодержат Comparable. В противном случае я бы порекомендовал вам реализовать этот интерфейс, как здесь:

public class Circle implements Comparable<Circle> {}

и, конечно, предоставьте свою собственную реализацию compareToметода, как здесь:

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

И тогда вы можете снова использовать, так Colection.sort(list)как теперь список содержит объекты типа Comparable и может быть отсортирован. Заказ зависит от compareToметода. Проверьте это https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html для получения более подробной информации.


11

Collections.sortпозволяет передать экземпляр, Comparatorкоторый определяет логику сортировки. Таким образом, вместо сортировки списка в естественном порядке и последующего его обращения, можно просто перейти Collections.reverseOrder()к нему sort, чтобы отсортировать список в обратном порядке:

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

Как упомянуто @ Marco13, помимо того, что он более идиоматичен (и, возможно, более эффективен), использование компаратора обратного порядка обеспечивает стабильность сортировки (это означает, что порядок элементов не изменится, если они равны по сравнению с компаратором, тогда как задний ход изменит порядок)


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;

    }
}

Похоже, что это Collections.synchronizedList помогает нам
vitalinvent

7

Вот краткая таблица, которая охватывает типичные случаи:

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

если вы используете Java SE 8, то это может помочь.

//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
Существует также Collections.reverseOrder()без каких-либо аргументов, что делает вашу реализацию compareDoubleизлишней (это эквивалентно естественному порядку Doubles). Ответ здесь должен бытьCollections.sort(testList, Collections.reverseOrder());
Мэтт

5

| * | Сортировка списка:

import java.util.Collections;

| => Порядок сортировки Asc:

Collections.sort(NamAryVar);

| => Сортировать Dsc Order:

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

| * | Обратный порядок списка:

Collections.reverse(NamAryVar);

4

Вы можете сделать так:

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

Коллекция имеет компаратор по умолчанию, который может помочь вам в этом.

Кроме того, если вы хотите использовать некоторые новые функции Java 8, вы можете сделать так:

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

3

Например, у меня есть класс Person: String name, int age ==> Конструктор new Person (имя, возраст)

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

В JAVA 8 теперь все намного проще.

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]

- Для обратного использования это

.sorted(Comparator.reverseOrder())

3

Вы можете использовать так

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

1

С Eclipse Collections вы можете создать примитивный двойной список, отсортировать его, а затем повернуть его в обратном порядке. Такой подход позволит избежать бокса в парном разряде.

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

Если вы хотите List<Double>, то следующее будет работать.

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

Если вы хотите сохранить тип как ArrayList<Double>, вы можете инициализировать и отсортировать список с помощью ArrayListIterateслужебного класса следующим образом:

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

Примечание: я являюсь коммиттером для Eclipse Collections .


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.