Comparator.compare()如何工作?

时间:2019-03-01 11:34:25

标签: java kotlin

在学习Kotlin的过程中,我试图了解Java的Comparator接口的工作方式-主要是compare()函数,以便我可以使用它。

我尝试阅读compare()的文档,但是我想对它的工作原理进行更简单的说明。

在迭代列表时,x中的ycompare(x, y)到底是什么?迭代时,它是否定位并比较每对数字吗?例如:

arrayOf(1, 2, 3, 4)

它将比较1和2(x和y),然后2和3(x和y),然后3和4(x和y)吗?

我有一个Kotlin函数,该函数提供一个比较器以对列表进行降序排序:

import java.util.*

fun getList(): List<Int> {
    val arrayList = arrayListOf(1, 5, 2)
    Collections.sort(arrayList, object: Comparator<Int> {
        override fun compare(x: Int, y: Int){
            return x < y
        }
    } )
    return arrayList

我不确定为什么上面的函数不是正确的语法。

4 个答案:

答案 0 :(得分:5)

它可以归结为javadoc的以下语句:

  

比较其两个参数的顺序。当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。

这就是全部。编写比较器时,您定义您想要的顺序。关键是您的方法将返回-1、0或1。这取决于您想要如何对这两个传入参数进行排序。 (是的,它不必为-1或1,只需为负,零,正)。

换句话说:关键是compare()在该合同中起作用。它在两个元素上定义了一个顺序。这就是全部。

在对数据进行排序时,每次在基础排序代码需要知道两个元素的顺序时都会调用它。因此,这些调用发生的确切“顺序”以及传递的参数取决于实际的排序算法以及要排序的数据。

从这个角度来看,您的问题意味着您对整个主题有过多的思考。简单理解:打算为对象/值定义“自定义”顺序时使用比较器。

并且没有必要为int,Int或Integer定义“自己的”比较器,因为这些类已经定义了它们的自然顺序,因此例如已经有Integer.compare()。为此类定义自己的比较器的唯一用例是当您要对它们进行不同排序时。但是最有可能的是,您仍然会使用现有的比较器功能,并使用其他内置方式,例如反转“自然”顺序。

答案 1 :(得分:3)

Comparator<T>只是比较T类型的任意两个元素的一种方式。

  

遍历列表时,compare(x,y)中的x和y到底是什么?

迭代时,根本不调用比较器。

当传递给Collections.sort()方法时,只要基础排序算法需要比较2个元素,就可以使用比较器。

  

我不确定为什么上面的函数不是正确的语法。

您当前的实现不满足documentationcompare()需要返回一个负整数,0或一个正整数,具体取决于两个元素之间如何关联。

答案 2 :(得分:2)

compare文档非常清楚:

  

返回负整数,零或正整数作为第一个   参数小于,等于或大于第二个。

因此,您必须从函数而不是布尔值中返回Int

要提供有效的Kotlin代码,请举一个示例:

val list = listOf(1, 5, 2)
list.sortedWith(Comparator { x, y ->
       x.compareTo(y)
})

可以使用不同的算法进行排序,但是它们将在内部使用compareToCollections文档给出了一个想法:

  

本文档中包含的多态算法文档   类通常包括实现的简要说明。   此类描述应视为实施说明,而不是   而不是规范的某些部分。实施者应该随便   替代其他算法,只要规范本身是   坚持。 (例如,排序所使用的算法不必   是一个合并排序,但必须稳定。)

答案 3 :(得分:1)

#dataframe is df #first define the function to use (in this case olga from python) olgafunction <- function(y) { olga <- system2('olga-compute_pgen', args=c("--humanTRB ", as.character(y[,2])), wait=TRUE, stdout=TRUE) y <- cbind(y, pgen=olga) } #now use this function for every row of the dataframe dfoutput <- foreach(dfrow=iter(df, by='row'), .combine=rbind) %do% olgafunction(dfrow) 仅是可以比较的类的接口。这是关于比较任何两个对象。仅此而已。来自文档:

  

@param o1要比较的第一个对象。

     

@param o2要比较的第二个对象。

     

@返回负整数,零或正整数作为              第一个参数小于,等于或大于              第二。

排序完全是另一回事。它使用比较器(在不知道如何比较两个元素的情况下很难对任何东西进行排序),因此您可以提供自己的对集合进行排序的方式。

但是如何排序?关于通过Comparator进行排序的所有知识,就是排序是稳定的。查看有关排序的更多信息:https://www.geeksforgeeks.org/sorting-algorithms/