Як сортувати 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:)
Полігном

1
@ Polygnome OP тільки сортує Doubles.
tckmn

3
Так, але ви можете сортувати їх різними способами, залежно від випадку використання. Іноді ви можете відсортувати їх за відстанню до 0. Я навіть не знаю про характеристики часу виконання reverse, але сортування за спаданням насправді може бути швидшим, ніж сортування за зростанням, а потім повернення назад. Більше того, використання реалізації списку, що підтримує 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

Використовуйте утильовий метод класу 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


Де розташований метод порівняння?
lippo

1
вам потрібно імпортувати: імпортувати статичний java.util.Comparator.comparing;
krmanish007

1
Він доступний з Java 1.7?
lippo

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

Використання лямбда можливе тому, що в інтерфейсі компаратора є лише один метод реалізації, і VM може зробити висновок, який метод реалізований. Оскільки типи парам можуть бути зроблені для висновку, їх не потрібно зазначати (тобто (a, b)замість (Double a, Double b). А оскільки тіло лямбда має лише один рядок, і метод, як очікується, поверне значення, returnслід зробити висновок і дужки не потрібні.


Це класно, дякую! Цей трохи компактніший: Collections.sort (testList, Comparator.reverseOrder ());
kavics

Ще компактніші: testList.sort (Comparator.reverseOrder ());
jonasespelita

29

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

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

Примітка: арг в лямбда заміняються при передачі на Double.compare, щоб переконатися, що сорт спадає


Для мене це найкраща відповідь, оскільки це також працює для сортування за допомогою об’єктів ... приклад locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));
Анас,

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)оскільки тепер список містить об'єкти Порівняного типу і їх можна сортувати. Замовлення залежить від compareToспособу. Перевірте це на https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html для отримання більш детальної інформації.


11

Collections.sortдозволяє передавати екземпляр a, 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;

| => Сортувати порядок вибору:

Collections.sort(NamAryVar);

| => Сортувати Dsc Порядок:

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: ім'я струни, 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())


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 .


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.