如何在 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 上发布的其他基于比较器的解决方案,但我没有按降序排序。
有好心人能帮帮我吗?
非常感谢!
如果比较 o1
和 o2
(其中 o1
是第一个),b
的 Comparator
需要 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
)。
如果 a
、b
或 c
是原始类型 int
、long
或 double
记得使用 comparingInt()
、comparingLong()
、comparingDouble()
、thenComparingInt()
等
我在 Java 中有一个 ArrayList,列表中的每个元素都是一个具有 3 个字段(a、b 和 c)的对象。 我应该按升序排列;如果 2 个元素对于 a 具有相同的值,则应按 b 降序排列它们;最后,如果 2 个元素即使对于 b 也具有相同的值,则应按 c 升序对它们进行排序。
我尝试了 Whosebug 上发布的其他基于比较器的解决方案,但我没有按降序排序。
有好心人能帮帮我吗? 非常感谢!
如果比较 o1
和 o2
(其中 o1
是第一个),b
的 Comparator
需要 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
)。
如果 a
、b
或 c
是原始类型 int
、long
或 double
记得使用 comparingInt()
、comparingLong()
、comparingDouble()
、thenComparingInt()
等