12

Сортировка ArrayList пользовательских объектов по свойству

14

Я прочитал о сортировке ArrayList с использованием Comparator, но во всех примерах люди использовали метод compareTo, который, согласно некоторым источникам, предназначен для строк.

Я хотел отсортировать ArrayList кастомных объектов по одному из их свойств: объекту Date (getStartDay()). Обычно я сравниваю их следующим образом: item1.getStartDate().before(item2.getStartDate()). Поэтому мне стало интересно, могу ли я написать что-то вроде этого:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}

Таким образом, возникает вопрос: как правильно реализовать кастомный компаратор для сортировки ArrayList объектов по их свойству Date? Правильный ли подход с использованием метода compare в данном случае, и как должна выглядеть реализация сравнения в рамках Comparator?

5 ответ(ов)

2

Классы, которые имеют естественный порядок сортировки (например, класс Number), должны реализовывать интерфейс Comparable. В то время как классы, которые не имеют естественного порядка сортировки (например, класс Chair), должны быть обеспечены компаратором (или анонимным классом компаратора).

Вот два примера:

public class Number implements Comparable<Number> {
    private int value;

    public Number(int value) { this.value = value; }
    public int compareTo(Number anotherInstance) {
        return this.value - anotherInstance.value;
    }
}

public class Chair {
    private int weight;
    private int height;

    public Chair(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }
    /* Пропускаем геттеры и сеттеры */
}

class ChairWeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getWeight() - chair2.getWeight();
    }
}

class ChairHeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getHeight() - chair2.getHeight();
    }
}

Использование:

List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);

List<Chair> chairs = new ArrayList<Chair>();
// Сортировка по весу:
Collections.sort(chairs, new ChairWeightComparator());
// Сортировка по высоте:
Collections.sort(chairs, new ChairHeightComparator());

// Также можно создать анонимные компараторы;
// Сортировка по цвету:
Collections.sort(chairs, new Comparator<Chair>() {
    public int compare(Chair chair1, Chair chair2) {
        ...
    }
});

Таким образом, следуя этим рекомендациям, вы сможете правильно реализовать сортировку объектов в Java в зависимости от того, имеет ли ваш класс естественный порядок или его необходимо задавать с помощью компараторов.

1

Чтобы отсортировать ArrayList, можно использовать следующий фрагмент кода:

Collections.sort(studList, new Comparator<Student>(){
    public int compare(Student s1, Student s2) {
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
    }
});

В этом коде используется метод Collections.sort(), который принимает два аргумента: список, который вы хотите отсортировать (в данном случае studList), и объект Comparator, реализующий логику сравнения. Здесь мы сравниваем объекты типа Student по их именам, игнорируя регистр с помощью compareToIgnoreCase(). Это позволяет сортировать студентов по их именам без учета заглавных и строчных букв.

0

Лямбда-выражения в Java 8

Если вы хотите отсортировать список студентов (studList) по имени, вы можете использовать лямбда-выражения для упрощения кода. Вот несколько способов сделать это:

Способ 1: Используя Collections.sort()

Collections.sort(studList, (Student s1, Student s2) -> {
    return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});

В этом примере мы передаем лямбда-выражение в метод Collections.sort(), которое сравнивает имена студентов без учета регистра.

Способ 2: Используя метод sort() на списке

Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c);

Во втором примере мы создаем компаратор в виде лямбда-выражения и затем применяем его прямо к списку studList с помощью метода sort().

Оба подхода позволяют удобно сортировать список студентов, используя возможности, предоставляемые Java 8. Выберите тот вариант, который лучше соответствует вашим требованиям!

0

В Java 8 вы можете использовать ссылку на метод для вашего компаратора следующим образом:

import static java.util.Comparator.comparing;

Collections.sort(list, comparing(MyObject::getStartDate));

Таким образом, вместо того чтобы писать анонимный класс или лямбда-выражение, вы можете использовать ссылку на метод MyObject::getStartDate, что делает код более лаконичным и читаемым.

0

Поскольку технологии постоянно появляются, ответ на этот вопрос может со временем изменяться. Я взглянул на LambdaJ, и это действительно интересный инструмент.

Вы можете попробовать решить данные задачи с помощью LambdaJ. Ссылка на проект: http://code.google.com/p/lambdaj/

Вот пример:

Сортировка в итеративном стиле

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
    public int compare(Person p1, Person p2) {
        return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
    }
});

Сортировка с использованием лямбда-выражения

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

Конечно, такая красота может повлиять на производительность (в среднем в 2 раза медленнее), но разве можно найти более читаемый код?

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь