在kotlin中使用比较器

在kotlin中使用比较器,kotlin,collections,comparator,Kotlin,Collections,Comparator,我不熟悉kotlin,如何使用集合比较对象 Collections.sort(list,myCustomComparator)这可以用与Java中几乎相同的方法完成: private val myCustomComparator = Comparator<CustomObject> { a, b -> when { (a == null && b == null) -> 0 (a == null) -> -

我不熟悉kotlin,如何使用
集合比较对象


Collections.sort(list,myCustomComparator)
这可以用与Java中几乎相同的方法完成:

private val myCustomComparator =  Comparator<CustomObject> { a, b ->
    when {
        (a == null && b == null) -> 0
        (a == null) -> -1
        else -> 1
    }
}
您可以使用with lambda(因为
Comparator
是一个Java接口,Kotlin允许您这样做)或匿名类对象

对于lambda,它将如下所示:

val customObjects = listOf(CustomObject(), CustomObject())
customObjects.sortedWith(myCustomComparator)
val customComparator = Comparator<CustomObject> { a, b ->
    if (a == null && b == null) {
        return 0;
    } else if (a == null) {
        return -1;
    } else if (b == null) {
        return 1;
    }
}
val customComparator=比较器{a,b->
如果(a==null&&b==null){
返回0;
}else if(a==null){
返回-1;
}else如果(b==null){
返回1;
}
}
和匿名类版本:

val customComparator = object: Comparator<CustomObject> {
    override fun compare(a: CustomObject, b: CustomObject): Int {
        if (a == null && b == null) {
            return 0;
        } else if (a == null) {
            return -1;
        } else if (b == null) {
            return 1;
        }
    }
}
val customComparator=object:Comparator{
覆盖乐趣比较(a:CustomObject,b:CustomObject):Int{
如果(a==null&&b==null){
返回0;
}else if(a==null){
返回-1;
}else如果(b==null){
返回1;
}
}
}

在Kotlin中有更好的方法对集合进行排序-您可以使用扩展功能
sorted,如下所示:

list.sortedWith(Comparator { s1, s2 ->
    when {
        s1 == null && s2 == null -> 0
        s1 == null -> -1
        else -> 1
    }
})

但请记住,这将返回列表的副本。

根据其他答案,相当直接的翻译可以让您对列表进行排序,例如:

fun myCustomComparator() = Comparator<CustomObject>{ a, b ->
    when {
        (a == null && b == null) -> 0
        (a == null) -> -1
        else -> 1
    }
}
然而,这里有一些潜在的问题

主要的一点是,它是不一致的
比较方
的总合同规定如下:

实施者必须确保所有x和y的
sgn(比较(x,y))==-sgn(比较(y,x))

(不幸的是,他们没有提到这些。他们没有达到Java的标准,真是太遗憾了。)

然而,上面的比较器没有做到这一点;如果a和b不为空,那么
compare(a,b)
compare(b,a)
都是1

这很可能导致问题;例如,根据sort()方法的编码方式,它可能使列表未排序,或永远无法完成。或者,如果将其用于已排序的映射,则映射可能无法返回其某些值,或永远无法完成

可以通过添加第四种情况来解决此问题:

fun <T> nullsFirstComparator() = Comparator<T>{ a, b ->
    when {
        (a == null && b == null) -> 0
        (a == null) -> -1
        (b == null) -> 1
        else -> 0
    }
}
但是,如果使用标准库功能,则可以简化:

fun <T : Comparable<T>> nullsFirstComparator()
    = Comparator<T>{ a, b -> compareValues(a, b) }

但是你不需要自己写,因为这已经在Kotlin标准库中了,就像

在考虑@Alexander答案后,代码可以写成

private val MyCustomComparator=比较器{a,b->
什么时候{
a==null&&b==null->return@Comparator0
a==null->return@Comparator -1
b==null->return@Comparator1.
其他->return@Comparator0
}

}
+1,不仅讨论了实际问题,还指出了可比和包括Kotlin标准库的基本要求。
fun <T : Comparable<T>> nullsFirstComparator() = Comparator<T>{ a, b ->
    when {
        (a == null && b == null) -> 0
        (a == null) -> -1
        (b == null) -> 1
        else -> a.compareTo(b)
    }
}
fun <T : Comparable<T>> nullsFirstComparator()
    = Comparator<T>{ a, b -> compareValues(a, b) }
fun <T> nullsFirstComparator(comparator: Comparator<T>) = Comparator<T>{ a, b ->
    when {
        (a == null && b == null) -> 0
        (a == null) -> -1
        (b == null) -> 1
        else -> c.compare(a, b)
    }
}