Kotlin Array.binarySearch技术疑问及自定义全序示例请求
Kotlin Array.binarySearch 相关问题解答
1. <out TypeVariable(T)> 的含义
这里的out是Kotlin的协变类型标注,TypeVariable(T)就是泛型参数T的规范写法,简化后为<out T>。它表示类型参数T是协变的——换句话说,这个binarySearch函数可以接受元素类型为T子类的Array实例。比如如果有父类Animal和子类Dog,Array<Dog>可以直接传给需要Array<Animal>的该函数,因为二分查找只读取数组元素、不会修改数组,这种类型转换是安全的。
2. 函数签名连贯解读
先把你给出的签名简化为标准写法:
fun <out T> Array<T>.binarySearch( element: T, comparator: Comparator<T>, fromIndex: Int = 0, toIndex: Int = size ): Int
逐部分解读:
fun <out T>:这是一个泛型函数,out T声明了协变的类型参数TArray<T>.:这是扩展函数,意味着所有元素类型为T的Array对象都能调用这个方法binarySearch:函数名,实现二分查找逻辑element: T:要查找的目标元素,类型与数组元素一致comparator: Comparator<T>:必须传入的比较器,用来定义T类型元素的全序关系——因为泛型T不像Int那样有默认的自然全序,所以需要通过比较器告诉函数如何判断元素的大小顺序fromIndex: Int = 0, toIndex: Int = size:可选参数,指定查找的起始(包含)和结束(不包含)索引,默认覆盖整个数组: Int:返回值为整数,找到元素时返回其索引;未找到时返回-(插入点)-1(插入点指元素应该插入的位置,以保持数组有序)
补充:IntArray不需要传比较器,是因为Int本身实现了Comparable<Int>,Kotlin为IntArray提供了专用的binarySearch重载,直接使用整数的自然全序。
3. 非常规全序的对象数组示例
下面是一个按名字长度降序、长度相同则按年龄升序的非常规全序示例,完全区别于默认的字母/数字序:
定义数据类与自定义全序
// 简单的数据类 data class Person(val name: String, val age: Int) fun main() { // 1. 定义自定义比较器,实现非常规全序 val customComparator = Comparator<Person> { p1, p2 -> // 优先按名字长度降序比较 val lengthComparison = p2.name.length.compareTo(p1.name.length) // 长度相同时,按年龄升序比较 if (lengthComparison != 0) lengthComparison else p1.age.compareTo(p2.age) } // 2. 创建数组并按自定义全序排序(二分查找要求数组必须提前有序) val sortedPeople = arrayOf( Person("Anna", 22), Person("Alexander", 30), Person("Bob", 25), Person("Catherine", 28) ).sortedWith(customComparator).toTypedArray() // 3. 目标查找元素 val target = Person("Bob", 25) // 4. 使用自定义比较器执行二分查找 val resultIndex = sortedPeople.binarySearch(target, customComparator) println("目标元素索引:$resultIndex") // 输出2,对应排序后数组的第三个元素 }
说明:这里的全序规则不是常规的名字字母序或年龄升序,而是以名字长度为第一优先级的倒序规则,属于典型的非常规全序。注意二分查找的前提是数组必须按照指定的全序提前排序,否则查找结果会不准确。
内容的提问来源于stack exchange,提问作者Mufasa
相关产品推荐
相关产品推荐

