Java的Collections.sort转Kotlin后报错,如何解决?
问题:Kotlin中实现Comparator排序时出现"Object is not abstract and does not implement abstract member"错误
我是Kotlin新手,现有一段Java代码用于对mHullList按轮廓面积降序排序:
Collections.sort(mHullList, new Comparator<MatOfPoint>() { @Override public int compare(MatOfPoint lhs, MatOfPoint rhs) { return Double.compare(Imgproc.contourArea(rhs),Imgproc.contourArea(lhs)); } });
经IDE转换为Kotlin代码后出现错误提示:"Object is not abstract and does not implement abstract member",转换后的Kotlin代码如下:
Collections.sort(mHullList, object : Comparator<MatOfPoint?> { fun compare(lhs: MatOfPoint, rhs: MatOfPoint): Int { return java.lang.Double.compare( Imgproc.contourArea(rhs), Imgproc.contourArea(lhs) ) } })
已知mHullList定义为:
val mHullList: MutableList<MatOfPoint> = ArrayList()
请问该如何解决此问题?
解决方法
问题根源:Kotlin实现Java的
Comparator接口时,必须显式用override标记重写的抽象方法,IDE转换的代码缺少该关键字;同时接口泛型的可空类型MatOfPoint?和列表的非空元素类型不匹配。修正方案一:正确实现Comparator接口
Collections.sort(mHullList, object : Comparator<MatOfPoint> { override fun compare(lhs: MatOfPoint, rhs: MatOfPoint): Int { return java.lang.Double.compare(Imgproc.contourArea(rhs), Imgproc.contourArea(lhs)) } })
关键调整:
- 给
compare方法添加override关键字,明确重写接口抽象方法 - 将泛型
MatOfPoint?改为MatOfPoint,和列表元素类型保持一致(非空)
- 修正方案二:使用Kotlin SAM转换简化代码
Kotlin支持用lambda直接替代单抽象方法接口,代码可简化为:
Collections.sort(mHullList) { lhs, rhs -> java.lang.Double.compare(Imgproc.contourArea(rhs), Imgproc.contourArea(lhs)) }
- 修正方案三:使用Kotlin风格的列表扩展函数
Kotlin的MutableList自带sortWith、sortByDescending等扩展函数,写法更简洁:
// 方式1:用sortWith搭配Comparator mHullList.sortWith(Comparator { lhs, rhs -> java.lang.Double.compare(Imgproc.contourArea(rhs), Imgproc.contourArea(lhs)) }) // 方式2:直接用sortByDescending指定排序键 mHullList.sortByDescending { Imgproc.contourArea(it) }
最后一种写法最符合Kotlin习惯,直接通过sortByDescending指定按轮廓面积降序排序。
内容的提问来源于stack exchange,提问作者cityvoice
相关产品推荐
相关产品推荐

