如何在 Java 中按不同顺序 (asc/desc) 的多个字段对列表进行排序?

How to sort a list by multiple fields in different orders (asc/desc) in Java?

我在 Java 中有一个 ArrayList,列表中的每个元素都是一个具有 3 个字段(a、b 和 c)的对象。 我应该按升序排列;如果 2 个元素对于 a 具有相同的值,则应按 b 降序排列它们;最后,如果 2 个元素即使对于 b 也具有相同的值,则应按 c 升序对它们进行排序。

我尝试了 Whosebug 上发布的其他基于比较器的解决方案,但我没有按降序排序。

有好心人能帮帮我吗? 非常感谢!

如果比较 o1o2(其中 o1 是第一个),bComparator 需要 return 一个负值参数和 o2 是第二个),并且 o1.b 大于 o2.b。当第一个参数相对较小(之前)第二个参数时,Comparator return 为负数。由于您希望将 b 值较大的元素解释为相对较小的元素,因此将 return 类型与典型的升序相反 Integer 进行比较。

  class Obj {
    int a;
    int b;
    int c;

    Obj(int a, int b, int c) {
      this.a = a;
      this.b = b;
      this.c = c;
    }

    @Override
    public String toString() {
      return "{a: " + a + ", b: " + b + ", c: " + c + "}";
    }
  }

  public void sortObjs() {
    ArrayList<Obj> list = new ArrayList<>();

    list.add(new Obj(0, 1, 2));
    list.add(new Obj(0, 2, 2));
    list.add(new Obj(1, 1, 2));
    list.add(new Obj(1, 1, 1));

    list.sort((o1, o2) -> {
      if (o1.a != o2.a) {
        return o1.a - o2.a;
      }
      //if Objects' a fields are equal but b is not, sort by b in descending order
      if (o1.b != o2.b) {
        return o2.b - o1.b;
      }
      return o1.c - o2.c;
    });

    System.out.println(list);

  }

  public static void main(String[] args) {
    new Main().sortObjs();
  }
}

输出:

[{a: 0, b: 2, c: 2}, {a: 0, b: 1, c: 2}, {a: 1, b: 1, c: 1}, {a: 1, b: 1, c: 2}]

Comparator.reversed() 为降序

    Comparator<Element> compar = Comparator.comparing(Element::getA)
            .thenComparing(Comparator.comparing(Element::getB).reversed())
            .thenComparing(Element::getC);
    yourArrayList.sort(compar);

除了 reversed 方法之外,我还利用了 thenComparing() 重载的事实:一个 thenComparing()Comparator 作为参数,我们需要它来反转,另一个只是将方法引用(或 lambda)作为参数(thenComparing() 声明中的 Function)。

如果 abc 是原始类型 intlongdouble 记得使用 comparingInt()comparingLong()comparingDouble()thenComparingInt()