Сортувати колекцію Java


78

У мене є колекція Java:

Collection<CustomObject> list = new ArrayList<CustomObject>();

CustomObjectзараз має idполе перед відображенням списку, я хочу відсортувати цю колекцію за цим id.

Чи можу я це зробити?


Відповіді:


156

Використовуйте компаратор :

List<CustomObject> list = new ArrayList<CustomObject>();
Comparator<CustomObject> comparator = new Comparator<CustomObject>() {
    @Override
    public int compare(CustomObject left, CustomObject right) {
        return left.getId() - right.getId(); // use your logic
    }
};

Collections.sort(list, comparator); // use the comparator as much as u want
System.out.println(list);

Крім того, якщо CustomObjectреалізує Comparable, то просто використовуйтеCollections.sort(list)

З JDK 8 синтаксис набагато простіший.

List<CustomObject> list = getCustomObjectList();
Collections.sort(list, (left, right) -> left.getId() - right.getId());
System.out.println(list);

Набагато простіше

List<CustomObject> list = getCustomObjectList();
list.sort((left, right) -> left.getId() - right.getId());
System.out.println(list);

Найпростіший

List<CustomObject> list = getCustomObjectList();
list.sort(Comparator.comparing(CustomObject::getId));
System.out.println(list);

Очевидно, що початковий код можна використовувати і для JDK 8.


Що робити, якщо вони хочуть сортувати більше одного разу?
— Hunter McMillen

Відповідь відредаговано, перевірте. Очевидно, що це не велика проблема, якщо зрозуміло, як користуватися компаратором. Якщо ви можете зробити це один раз, це можна зробити і разів :)
— Kowser

Так ... якщо клас реалізує порівняно, тоді не потрібно передавати компаратор ... приємно ..ta
— Makky

6
Метод сортування (List <T>, Comparator <? Super T>) у типі Collections не застосовується для аргументів (Collection, Comparator); ви не можете передавати метод Collection для сортування, який мертво дратує
— gibffe

5
Метод сортування працює для списків, а не для колекцій. Для роботи цього прикладу тип змінної списку слід змінити на Список.
— Ерік Василік

34

Питання: "Сортувати колекцію". Тож користуватися не можна Collections.sort(List<T> l, Comparator<? super T> comparator).

Кілька порад:

Для типу колекції:

Comparator<String> defaultComparator = new Comparator<String>() {
   @Override
   public int compare(String o1, String o2) {
       return o1.compareTo(o2);
   }
};

Collection<String> collection = getSomeStringCollection();
String[] strings = collection.toArray(new String[collection.size()]);
Arrays.sort(strings, defaultComparator);
List<String> sortedStrings = Arrays.asList(strings);

Collection<String> collection = getSomeStringCollection();
List<String> list = new ArrayList(collection);
Collections.sort(list, defaultComparator);
collection = list; // if you wish

Для типу списку:

List<String> list = getSomeStringList();
Collections.sort(list, defaultComparator);

Для типу набору:

Set<String> set = getSomeStringSet();
// Than steps like in 'For Collection type' section or use java.util.TreeSet
// TreeSet sample:
// Sorted using java.lang.Comparable.
Set<String> naturalSorted = new TreeSet(set);

Set<String> set = getSomeStringSet();
Set<String> sortedSet = new TreeSet(defaultComparator);
sortedSet.addAll(set);

Версія Java 8. Є java.util.List#sort(Comparator<? super E> c)метод

List<String> list = getSomeStringList();
list.sort(defaultComparator);

або

List<String> list = getSomeStringList();
list.sort((String o1, String o2) -> o1.compareTo(o2));

або для типів, що реалізує Порівнянний:

List<String> list = getSomeStringList();
list.sort(String::compareTo);

Я задав це питання 4 роки тому, а ви відповідаєте зараз.
— Маккі

8
Дякую за відповідь. Дійсно ціную це. 4 роки, і все ще неправильна відповідь позначена як правильна. Хто такий поганий хлопець?
— Aliaksei Yatsau

2
@Makky, оскільки відповідає за список, а не за колекцію
— NimChimpsky

11

Дещо інший приклад каже, якщо у вас є клас, який не реалізує порівняльний, але ви все одно хочете відсортувати його за полем чи методом.

Collections.sort(allMatching, new Comparator<ClassOne>() {
  @Override public int compare(final ClassOne o1, final ClassOne o2) {
    if (o1.getMethodToSort() > o2.getMethodToSort()) {
      return 1;
    } else if (o1.getMethodToSort() < o2.getMethodToSort()) {
      return -1;
    }  
    return 0;
  }
});

Застосований вами оператор if робить саме те, compareTo()що вже робить.
— Hunter McMillen

Різниця полягає в тому, що в цьому прикладі клас ClassOne не є порівнянним класом, він не реалізує Comparable. Я просто намагався показати приклад того, як ви можете використовувати колекцію та компаратор для сортування не порівнянних об’єктів. ClassOne не має методу порівнянняЗ ..
— Шон Вейдер

не працює з java 6 (Collections.sort обмежений списком)
— phil294

Ви не знайдете Collections.sort, який приймає Set в Java 7 або 8. За визначенням List є впорядкованою послідовністю елементів, тоді як Set - це окремий список елементів, який не впорядкований. Якщо ви хочете замовити набір, подивіться на TreeSet
— Shawn Vader

7

Ви повинні впровадити Comparator інтерфейс.

приклад:

public class CustomComparator implements Comparator<CustomObject> 
{
    @Override
    public int compare(CustomObject o1, CustomObject o2) {
        return o1.getId().compareTo(o2.getId());
    }
}

Тоді ви можете використовувати Collections.sort()метод колекцій класів :

Collections.sort(list, new CustomComparator());


5

Багато правильних відповідей, але я не знайшов цієї: колекції не можна сортувати, ви можете лише переглядати їх.

Тепер ви можете переглядати їх і створювати нові відсортовані something. Дотримуйтесь відповідей тут для цього.



4

Починаючи з Java 8, тепер ви можете робити це з потоком, використовуючи лямбда:

list.stream().sorted(Comparator.comparing(customObject::getId))
             .foreach(object -> System.out.println(object));

2

Використовуйте сортування .

Вам просто потрібно зробити це:

Усі елементи у списку повинні реалізовувати порівнянний інтерфейс.

(Або скористайтеся версією під ним, як вже говорили інші.)


0

SortedSet та Comparator. Компаратор повинен виконувати поле ідентифікатора .


@Qwerky - Я знаю, що у нього є список. Я пропоную йому скористатися набором. Якщо він не хоче підтримувати дублікати та порядок вставки.
— Aravind Yarram

0

У Java 8 у вас є кілька варіантів, що поєднують посилання на методи та вбудований comparingкомпаратор:

import static java.util.Comparator.comparing;

Collection<CustomObject> list = new ArrayList<CustomObject>();

Collections.sort(list, comparing(CustomObject::getId));
//or
list.sort(comparing(CustomObject::getId));

0

Ви можете використовувати спеціальний клас Java для сортування.


-1

Ви також можете використовувати:

Collections.sort(list, new Comparator<CustomObject>() {
    public int compare(CustomObject obj1, CustomObject obj2) {
        return obj1.id - obj2.id;
    }
});
System.out.println(list);

-3

Щоб бути надзвичайно зрозумілим, Collection.sort (list, compartor) нічого не повертає, тому щось подібне list = Collection.sort(list, compartor);видасть помилку (void не може бути перетворено на [type type]) і замість цього має бутиCollection.sort(list, compartor)


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