如何在 Java 中对对象列表按一个属性升序排序,然后按另一个属性降序排序?

问题描述 投票:0回答:1

我想对对象列表按某个属性升序排序,然后按另一个属性降序排序。

例如,将以下列表视为

(age, name)

(25, Alice), (25, Bob), (30, Charlie), (25, David), (30, Eve)

我试图按年龄升序排序,然后按名称降序排序,如下所示:

(25, David), (25, Bob), (25, Alice), (30, Eve), (30, Charlie)

我尝试使用

Stream.sorted
Comparator
来实现此目的,但我不确定如何在不反转之前的比较器的情况下反转
Comparator.thenComparing

看看这个例子:

import java.util.Comparator;
import java.util.List;

public class Dummy {

  private static class Person {

    private final int age;
    private final String name;

    public Person(int age, String name) {
      this.age = age;
      this.name = name;
    }

    public int getAge() { return age; }

    public String getName() { return name; }

    @Override
    public String toString() { return "(" + age + ", " + name + ")"; }
  }

  public static void main(String[] args) {
    var people = List.of(
      new Person(25, "Alice"),
      new Person(25, "Bob"),
      new Person(30, "Charlie"),
      new Person(25, "David"),
      new Person(30, "Eve")
    );

    System.out.println(people);

    var sortedPeople = people
      .stream()
      .sorted(
        Comparator
          .comparing(Person::getAge)
          .thenComparing(Person::getName)
          .reversed()
      )
      .toList();

    System.out.println(sortedPeople);
  }
}

如您所见,我将

reversed
应用于比较器,但结果比较变为

年龄按降序排列,然后姓名按降序排列:

(30, Eve), (30, Charlie), (25, David), (25, Bob), (25, Alice)

但正如我上面所说,我想要实现的比较是

年龄按升序排列,然后姓名按降序排列:

(25, David), (25, Bob), (25, Alice), (30, Eve), (30, Charlie)
java sorting
1个回答
0
投票

您当前的代码正在创建一个比较器,以自然升序比较年龄和姓名,然后反转 that 比较器。只需要反转名称的比较即可,实现起来比较简单。

  1. 使用

    Comparator#thenComparing(Function,Comparator)
    过载。第二个参数是一个比较器,告诉它如何比较函数提取的对象。

  2. 使用

    Comparator.reverseOrder()
    获得一个反转自然顺序的比较器。

例如:

import static java.util.Comparator.comparing;
import static java.util.Comparator.reverseOrder;

import java.util.ArrayList;

public class Main {

  public static void main(String[] args) throws Exception {
    var people = new ArrayList<Person>(5);
    people.add(new Person(25, "Alice"));
    people.add(new Person(25, "Bob"));
    people.add(new Person(30, "Charlie"));
    people.add(new Person(25, "David"));
    people.add(new Person(30, "Eve"));
    printPeople("UNSORTED", people);

    people.sort(comparing(Person::age).thenComparing(Person::name, reverseOrder()));
    printPeople("SORTED", people);
  }

  static void printPeople(String label, Iterable<Person> people) {
    System.out.println(label);
    System.out.println("-".repeat(label.length()));
    people.forEach(System.out::println);
    System.out.println();
  }

  record Person(int age, String name) {}
}

输出:

UNSORTED
--------
Person[age=25, name=Alice]
Person[age=25, name=Bob]
Person[age=30, name=Charlie]
Person[age=25, name=David]
Person[age=30, name=Eve]

SORTED
------
Person[age=25, name=David]
Person[age=25, name=Bob]
Person[age=25, name=Alice]
Person[age=30, name=Eve]
Person[age=30, name=Charlie]

© www.soinside.com 2019 - 2024. All rights reserved.