Сортировка списка в Java с использованием 2 критериев

У меня есть список объектов. Каждый объект содержит String и Date (среди прочих).

Я хочу сначала отсортировать по String, а затем по Date.

Как это можно сделать самым чистым способом?

Спасибо!

Krt_Malta​​p >

Ответ 1

Учитывая класс объекта, который выглядит следующим образом:

public class MyObject {
    public String getString() { ... }
    public Date getDate() { ... }
    ...
}

Напишите собственный класс компаратора следующим образом:

public class ObjectComparator implements Comparator{

    public int compare(Object obj1, Object obj2) {
        MyObject myObj1 = (MyObject)obj1;
        MyObject myObj2 = (MyObject)obj2;
        stringResult = myObj1.getString().compareTo(myObj2.getString());
        if (stringResult == 0) {
            // Strings are equal, sort by date
            return myObj1.getDate().compareTo(myObj2.getDate());
        }
        else {
            return stringResult;
        }
    }
}

Затем сортируйте следующим образом:

Collections.sort(objectList, new ObjectComparator());

Ответ 2

С Java 8 это очень просто. Учитывая,

class MyClass {
    String getString() { ... }
    Date getDate() { ... }
}

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

List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));

Ответ 3

Ответ компараторов правильный, но неполный.

StringAndDateComparator implements Comparator<MyObject> {

   public int compare(MyObject first, MyObject second) {
        int result = first.getString().compareTo(second.getString());
        if (result != 0) {
            return result;
        }
        else {
            return first.getDate().compareTo(second.getDate());
        }
}

GlazedLists имеет хороший метод утилиты для объединения разных компараторов, чтобы избавить вас от написания этого шаблона. Дополнительную информацию см. В chainComparators.

Ответ 4

Внедрите Comparator, используя compare(a,b), как показано ниже:

Обычная Java:

 public int compare(YourObject o1, YourObject o2) {
    int result = o1.getProperty1().compareTo(o2.getProperty1()));
    if(result==0) result = o1.getProperty2().compareTo(o2.getProperty2());
    return result;
 }

С Guava (используя ComparisonChain):

public int compare(YourObject o1, YourObject o2) {
    return ComparisonChain.start()
      .compare(o1.getProperty1(), o2.getProperty1())
      .compare(o1.getProperty2(), o2.getProperty2())
      .result();
 }

С Commons/Lang (используя CompareToBuilder):

public int compare(YourObject o1, YourObject o2) {
    return new CompareToBuilder()
      .append(o1.getProperty1(), o2.getProperty1())
      .append(o1.getProperty2(), o2.getProperty2())
      .toComparison();
 }

(Все три версии эквивалентны, но простая Java-версия является самой многословной и, следовательно, самой подверженной ошибкам. Все три решения предполагают, что o1.getProperty1() и o1.getProperty2() реализуют Comparable).

(взято из этого предыдущего моего ответа)


теперь Collections.sort(yourList, yourComparator)

Ответ 5

Попробуйте этот метод:

Collections.sort(list, comparator)

Разумеется, для вашего объекта должна быть реализована пользовательская реализация Comparator, как указано Manoj.

Ответ 6

Используя java 8 и метод параллельной сортировки, мы также можем добиться этого следующим образом:

List<Employee> empss  = getEmployees();
Comparator<Employee> combinedComparator = Comparator.comparing(Employee::getFName)
                                                    .thenComparing(Employee::getLName);
Employee[] emppArr = employees.toArray(new Employee[empss.size()]);

//Parallel sorting
Arrays.parallelSort(emppArr, combinedComparator);