Java中按地理位置经纬度距离升序排序的核心是使用Haversine公式计算两点间球面距离(单位米),再通过Comparator比较距离值;需将经纬度转为弧度,地球半径取6371000米,参考点参与每次计算,Comparator依赖外部坐标故需按需新建。

Java 中实现按地理位置经纬度距离升序排序,核心是用 Comparator 计算两点间球面距离(如 Haversine 公式),再基于距离值比较。不需要引入第三方地理库,纯 Java 即可完成。
使用 Haversine 公式计算两点间距离
Haversine 公式能较准确地计算地球表面两点间的最短距离(单位:米或千米)。注意输入为弧度,需将经纬度从度转为弧度(Math.toRadians())。
- 地球平均半径取 6371000 米(或 6371.0 千米)
- 公式关键步骤:先算纬度差、经度差的正弦平方,再套入 Haversine 主式
- 返回距离值用于后续比较,建议统一用米,避免浮点精度干扰排序
定义待排序对象并封装坐标
假设你有一个地点类,比如 Location,至少包含 latitude 和 longitude 字段:
public class Location {
private String name;
private double latitude; // 纬度
private double longitude; // 经度
// 构造、getter 省略
}排序时需指定一个参考点(例如用户当前位置),该点作为基准参与每次距离计算。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
编写 Distance-based Comparator
创建一个接收参考坐标的 Comparator 实现,推荐用 Lambda 或匿名内部类:
double refLat = 39.9042; // 北京纬度
double refLng = 116.4074; // 北京经度
<p>Comparator<Location> byDistance = (l1, l2) -> {
double d1 = haversineDistance(refLat, refLng, l1.getLatitude(), l1.getLongitude());
double d2 = haversineDistance(refLat, refLng, l2.getLatitude(), l2.getLongitude());
return Double.compare(d1, d2); // 升序:距离小的在前
};其中 haversineDistance 方法如下:
private static double haversineDistance(double lat1, double lng1, double lat2, double lng2) {
double r = 6371000; // 地球平均半径,单位:米
double lat1Rad = Math.toRadians(lat1);
double lat2Rad = Math.toRadians(lat2);
double lng1Rad = Math.toRadians(lng1);
double lng2Rad = Math.toRadians(lng2);
<pre class="brush:php;toolbar:false;">double dLat = lat2Rad - lat1Rad;
double dLng = lng2Rad - lng1Rad;
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return r * c;}
应用排序并验证结果
直接传给 list.sort() 或 Collection.sort():
List<Location> locations = ...; locations.sort(byDistance); // 升序:离参考点最近的排第一
注意:该 Comparator 不是静态复用型(依赖外部参考点),每次换参考位置需新建 Comparator;若频繁调用,可封装为工厂方法返回新实例。

















