Kotlin中如何按与当前设备坐标的距离对Location列表排序
按坐标距离排序Location列表的几种实现方式
首先,我们需要一个计算两个Location之间距离(或距离平方,排序时用平方更高效,因为开根号不影响大小比较)的辅助函数。另外注意你的Location类中属性名用了Long(大写L),这和Kotlin的Long类型重名,建议改成lon或long避免混淆,下面示例中会保留你的原属性名,但建议修改。
// 计算两点间欧几里得距离的平方(排序无需开根号,提升效率) fun Location.distanceSquaredTo(other: Location): Double { val latDiff = this.lat - other.lat val longDiff = this.Long - other.Long return latDiff * latDiff + longDiff * longDiff }
方法1:使用sortBy快速排序
sortBy是Kotlin集合的扩展函数,接收一个lambda表达式,返回用于排序的依据值,默认按该值升序排列(正好符合“由近到远”的需求)。
直接调用即可完成排序:
locations.sortBy { it.distanceSquaredTo(myLocation) }
这个方法最简洁,适合简单的排序场景。
方法2:使用sortWith配合Comparator
sortWith需要传入一个Comparator实例,用于定义两个元素的比较规则,适合需要自定义复杂排序逻辑的场景。
2.1 用Comparator.compareBy快速构建
和sortBy逻辑类似,只是通过Comparator的方式传入排序依据:
locations.sortWith(Comparator.compareBy { it.distanceSquaredTo(myLocation) })
2.2 自定义完整Comparator实现
如果需要额外的排序逻辑(比如距离相同时按纬度排序),可以手动实现Comparator:
locations.sortWith(object : Comparator<Location> { override fun compare(a: Location, b: Location): Int { val distanceA = a.distanceSquaredTo(myLocation) val distanceB = b.distanceSquaredTo(myLocation) // 升序排列:a更近返回-1,相等返回0,b更近返回1 return distanceA.compareTo(distanceB) } })
也可以用lambda简化写法:
locations.sortWith(Comparator { a, b -> val distanceA = a.distanceSquaredTo(myLocation) val distanceB = b.distanceSquaredTo(myLocation) distanceA.compareTo(distanceB) })
补充:真实地理经纬度的距离计算
如果你的坐标是真实的地球经纬度,欧几里得距离会有误差,建议使用Haversine公式计算球面距离:
const val EARTH_RADIUS = 6371000.0 // 地球平均半径,单位:米 fun Location.haversineDistanceTo(other: Location): Double { val lat1 = Math.toRadians(this.lat) val lon1 = Math.toRadians(this.Long) val lat2 = Math.toRadians(other.lat) val lon2 = Math.toRadians(other.Long) val dLat = lat2 - lat1 val dLon = lon2 - lon1 val a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2) val c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) return EARTH_RADIUS * c // 返回两点间球面距离,单位:米 }
使用时只需要把排序逻辑中的distanceSquaredTo替换成haversineDistanceTo即可,排序方式完全一致。
内容的提问来源于stack exchange,提问作者Joel Delgado
相关产品推荐
相关产品推荐

