Kotlin中使用compareBy处理IntArray时如何获取a、b参数?
解决Kotlin中compareBy比较二维点距离的问题
你遇到的核心问题是对compareBy的用法理解有误:compareBy的lambda参数是单个元素(即待比较集合中的每一个元素),而不是两个要对比的元素a和b。它的作用是把每个元素映射为一个可比较的值(比如距离平方),然后自动基于这个值完成元素间的排序。
正确实现方式1:用compareBy映射距离平方
针对你的二维点(IntArray(x,y)),计算每个点到原点的距离平方(无需开根号,不影响排序结果),作为compareBy的映射值即可:
val compareByDistance: Comparator<IntArray> = compareBy { point -> // 计算x² + y² point[0] * point[0] + point[1] * point[1] } val points = PriorityQueue<IntArray>(compareByDistance) points.add(intArrayOf(1, 2)) // 距离平方1+4=5 points.add(intArrayOf(2, 3)) // 距离平方4+9=13 // 此时PriorityQueue会按距离从小到大排序,出队顺序是(1,2) -> (2,3)
如果需要从远到近排序,只需要给距离平方加负号:
val compareByDistance: Comparator<IntArray> = compareBy { - (it[0] * it[0] + it[1] * it[1]) }
正确实现方式2:直接自定义Comparator(如果需要直接操作a和b)
如果你一定要直接获取两个对比元素a和b,可以直接使用Comparator的构造函数,跳过compareBy:
val compareByDistance = Comparator<IntArray> { a, b -> val distanceA = a[0] * a[0] + a[1] * a[1] val distanceB = b[0] * b[0] + b[1] * b[1] // 从小到大排序:返回distanceA与distanceB的比较结果 distanceA.compareTo(distanceB) // 从大到小排序则改为:distanceB.compareTo(distanceA) }
为什么你之前的代码无法访问a和b?
你贴的compareBy源码显示,它内部封装了Comparator的逻辑,把传入的selector函数分别应用到a和b上,再用compareValuesBy对比结果。也就是说,compareBy已经帮你处理了a和b的对比逻辑,你只需要告诉它每个元素要映射成什么值来参与比较即可。
内容的提问来源于stack exchange,提问作者gmmo
相关产品推荐
相关产品推荐

