0

I try to use the list extension function binarySearch

public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>,
fromIndex: Int = 0, toIndex: Int = size): Int

This is my definition:

open class Z
open class ZZ : Z()
open class ZZZ : ZZ()
open class ZZZZ : ZZZ()

val list: List<ZZZZ> = listOf()
val a0 = list.binarySearch("text", stringComparator) <-- error
val a1 = list.binarySearch("text", anyComparator)
val a2 = list.binarySearch(Z(), zComparator)
val a3 = list.binarySearch(ZZ(), zzComparator)
val a4 = list.binarySearch(ZZZ(), zzzComparator)

val stringComparator = Comparator<String> { o1, o2 -> o1.length.compareTo(o2.length) }
val anyComparator = Comparator<Any> { o1, o2 -> o1.hashCode().compareTo(o2.hashCode()) }
val zComparator = Comparator<Z> { o1, o2 -> o1.hashCode().compareTo(o2.hashCode()) }
val zzComparator = Comparator<ZZ> { o1, o2 -> o1.hashCode().compareTo(o2.hashCode()) }
val zzzComparator = Comparator<ZZZ> { o1, o2 -> o1.hashCode().compareTo(o2.hashCode()) }

The function binarySearch can not accept the String type but can accept the supertype of ZZZZ. I think the first parameter only accept ZZZZ type because List < T > is defined, but why it can accept all the supertype of ZZZZ?

UPDATE:

I create a list extension function like this:

fun <T> List<T>.ccc(t: T): Boolean {
    return contains(t)
} 

val list = listOf<ZZZZ>()
list.ccc("Q")
list.ccc(0)
list.ccc(mutableListOf<String>())
list.ccc(Z())
list.ccc(ZZ())
list.ccc(ZZZ())

I found it can accept many kind of type, the related question like this: How to write strongly typed generic extension function in Kotlin?

Is the binarySearch() function same as the ccc()?

Why ccc() can accept not only ZZZZ's supertype but also others?

Thanks for your help again!

mark
  • 133
  • 1
  • 7

1 Answers1

0

Because List is covariant, so a List<ZZZZ> is also a List<Z>, a List<Any> etc. So in cases a1 to a4 there is a suitable T which can be inferred and they compile.

If you really want to avoid it you could create an invariant wrapper

class InvariantList<T>(val x: List<T>)

public fun <T> InvariantList<T>.binarySearch(element: T, comparator: Comparator<in T>, fromIndex: Int = 0, toIndex: Int = size): Int = x.binarySearch(element, comparator, fromIndex, toIndex)

val list: InvariantList<ZZZZ> = InvariantList(listOf())

Now

val a0 = list.binarySearch("text", stringComparator)
val a1 = list.binarySearch("text", anyComparator)
val a2 = list.binarySearch(Z(), zComparator)
val a3 = list.binarySearch(ZZ(), zzComparator)
val a4 = list.binarySearch(ZZZ(), zzzComparator)

all will fail to compile.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487