在 Array.sort() 中实现 Java 比较器
Implement Java Comparator in Array.sort()
假设我有一个二维数组数组,代表我要比较的点。例如,我可以比较与原点的距离。我能做的是创建一个 class Point
:
class Point implements Comparable<Point>{
// class variables, constructor
public int compareTo(Point p) {
return (x*x + y*y).compareTo(p.x*p.x + p.y*p.y);
}
}
并用所有点填充 Point
类型的数组,然后使用 Array.sort(pointsArray)
。
也可以通过以下方式完成:
1) Arrays.sort(points, Comparator.comparing(p -> p[0]*p[0] + p[1]*p[1]));
或
2) Arrays.sort(points, (p1, p2) -> p1[0]*p1[0] + p1[1]*p1[1] - p2[0]*p2[0] - p2[1]*p2[1]);
没有创建任何新的数据类型。
可以在 问题中找到解释。
现在,如果我需要先比较 x 坐标,如果比较结果没有差异,再比较 y 坐标怎么办,即:
class Point implements Comparable<Point>{
// class variables, constructor
public int compareTo(Point p) {
int cmp = x.compareTo(p.x);
if(cmp == 0) return y.compareTo(p.y);
return cmp;
}
}
如何在 1) 和 2) 中翻译?
尽可能走最短的路,例如Comparator.comparing(Point::getX).thenComparing(Point::getY)
.
没有理由使用更长的版本。它们的可读性较差,而且很容易出错。例如,这是一种可能的实现方式
(p1, p2) -> {
if(p1.x == p2.x) {
return p1.y.compareTo(p2.y);
}
return p1.x.compareTo(p2.x);
}
需要更长的时间才能理解那里发生的事情,不是吗?
只需使用括号为 lambda 函数起一个更大的名称space 进行比较
Arrays.sort(points, (p1, p2) -> {
int x1 = p1[0];
int x2 = p2[0];
int y1 = p1[1];
int y2 = p2[1];
// just for readability no need to make local variables
if(x1 == x2){
// compare y1 and y2 values here return 1 for greater 0 for equal -1 for less then
}else{
// x compare
}
});
假设我有一个二维数组数组,代表我要比较的点。例如,我可以比较与原点的距离。我能做的是创建一个 class Point
:
class Point implements Comparable<Point>{
// class variables, constructor
public int compareTo(Point p) {
return (x*x + y*y).compareTo(p.x*p.x + p.y*p.y);
}
}
并用所有点填充 Point
类型的数组,然后使用 Array.sort(pointsArray)
。
也可以通过以下方式完成:
1) Arrays.sort(points, Comparator.comparing(p -> p[0]*p[0] + p[1]*p[1]));
或
2) Arrays.sort(points, (p1, p2) -> p1[0]*p1[0] + p1[1]*p1[1] - p2[0]*p2[0] - p2[1]*p2[1]);
没有创建任何新的数据类型。
可以在
现在,如果我需要先比较 x 坐标,如果比较结果没有差异,再比较 y 坐标怎么办,即:
class Point implements Comparable<Point>{
// class variables, constructor
public int compareTo(Point p) {
int cmp = x.compareTo(p.x);
if(cmp == 0) return y.compareTo(p.y);
return cmp;
}
}
如何在 1) 和 2) 中翻译?
尽可能走最短的路,例如Comparator.comparing(Point::getX).thenComparing(Point::getY)
.
没有理由使用更长的版本。它们的可读性较差,而且很容易出错。例如,这是一种可能的实现方式
(p1, p2) -> {
if(p1.x == p2.x) {
return p1.y.compareTo(p2.y);
}
return p1.x.compareTo(p2.x);
}
需要更长的时间才能理解那里发生的事情,不是吗?
只需使用括号为 lambda 函数起一个更大的名称space 进行比较
Arrays.sort(points, (p1, p2) -> {
int x1 = p1[0];
int x2 = p2[0];
int y1 = p1[1];
int y2 = p2[1];
// just for readability no need to make local variables
if(x1 == x2){
// compare y1 and y2 values here return 1 for greater 0 for equal -1 for less then
}else{
// x compare
}
});