Java中Comparator按曼哈顿距离排序Point的核心是:先确定参考原点(如(0,0)或任意点),再计算|x₁−x₀|+|y₁−y₀|,最后用Integer.compare(d1,d2)升序比较。

Java 中 Comparator 对 Point(x, y) 按曼哈顿距离排序,核心是:**先确定参考原点(比如原点 (0, 0) 或某指定点),再按 |x₁ − x₀| + |y₁ − y₀| 计算距离,最后用该值比较两个点。**
明确曼哈顿距离的计算逻辑
曼哈顿距离不是欧氏距离,不涉及平方和开根,而是横纵坐标绝对差之和:
- 若以原点
(0, 0)为基准,点p的距离为Math.abs(p.x) + Math.abs(p.y) - 若以任意参考点
origin = (ox, oy)为基准,距离为Math.abs(p.x - ox) + Math.abs(p.y - oy) - Comparator 只需返回这两个距离的差值(升序),Java 会自动处理正负逻辑
用 Lambda 表达式实现简洁排序
假设使用 Java 内置的 java.awt.Point(或自定义 Point 类,含 public int x, y 字段):
List<point> points = Arrays.asList(
new Point(3, 1), // 距原点 |3|+|1| = 4
new Point(-1, 2), // 距原点 |-1|+|2| = 3
new Point(0, -4) // 距原点 |0|+|-4| = 4
);
<p>// 按到原点 (0, 0) 的曼哈顿距离升序
points.sort((p1, p2) -> {
int d1 = Math.abs(p1.x) + Math.abs(p1.y);
int d2 = Math.abs(p2.x) + Math.abs(p2.y);
return Integer.compare(d1, d2); // 推荐用 Integer.compare 避免溢出
});
// 结果:[(-1,2), (3,1), (0,-4)] —— 距离分别为 3, 4, 4
</p></point>
封装成可复用的 Comparator(支持任意原点)
为提升复用性,可定义一个带参考点的比较器:
public class ManhattanDistanceComparator implements Comparator<point> {
private final int originX, originY;
<pre class="brush:php;toolbar:false;">public ManhattanDistanceComparator(int originX, int originY) {
this.originX = originX;
this.originY = originY;
}
@Override
public int compare(Point p1, Point p2) {
int d1 = Math.abs(p1.x - originX) + Math.abs(p1.y - originY);
int d2 = Math.abs(p2.x - originX) + Math.abs(p2.y - originY);
return Integer.compare(d1, d2);
}}
// 使用示例:按到点 (1, 1) 的距离排序 points.sort(new ManhattanDistanceComparator(1, 1));
注意点与常见坑
-
避免直接相减:写成
d1 - d2可能整数溢出(虽然曼哈顿距离通常不大,但安全起见用Integer.compare(d1, d2)) -
自定义 Point 类需确保字段可访问:若 x/y 是 private,需提供 getter 方法,Comparator 中调用
p.getX()和p.getY() -
稳定性:曼哈顿距离相等时,
sort()默认保持原有相对顺序(稳定排序),无需额外处理 -
空值处理:若列表可能含 null,需在 compare 中先判空,否则抛
NullPointerException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











