Сортувати колекцію 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.