UmAnusorn
UmAnusorn

Reputation: 11184

How to pass an array of integers to a method expecting `Array<T>`?

I have converted java shellSort to Kotlin. The problem is I have no idea to call this method.

Java

package Sorts;
public class ShellSort extends Sorter{

@Override
public <T extends Comparable<? super T>> void sort(T[] a) {
    int h = 1;
    while((h*3+1) < a.length)
        h = 3*h+1;
    while(h > 0){
        for(int i = h-1; i < a.length; i++){
            T s = a[i];
            int j = i;
            for(j = i; (j>=h) && (a[j-h].compareTo(s) > 0); j-=h)
                a[j] = a[j-h];
            a[j] = s;
        }
        h /= 3;
    }
}
}

Kotlin

fun <T : Comparable<T>> shellSort(a: Array<T>) {
    var h = 1
    while (h * 3 + 1 < a.size)
        h = 3 * h + 1
    while (h > 0) {
        for (i in h - 1..a.size - 1) {
            val s = a[i]
            var j = i
            j = i
            while (j >= h && a[j - h].compareTo(s) > 0) {
                a[j] = a[j - h]
                j -= h
            }
            a[j] = s
        }
        h /= 3
    }
}

What I have tried to call is cast intArray to array

 val array = intArrayOf(5, 3, 0, 2, 4, 1, 0, 5, 2, 3, 1, 4)
 shellSort(arrayOf(array))

Which comes with error

enter image description here

Type parameter bound for T in 

 fun <T : Comparable<T>> shellSort(a: Array<T>) : Unit

is not satisfied: inferred type IntArray is not a subtype of Comparable<IntArray>

Upvotes: 2

Views: 1246

Answers (2)

miensol
miensol

Reputation: 41678

intArrayOf returns IntArray which does not extend Array<Int> as one might assume. As stated in the documentation Kotlin provides specialized array types for various primitives that avoid boxing overhead. IntArray corresponds to Java's int[]. The ShellSort.sort method (both Kotlin and Java) requires boxed versions.

You can convert IntArray to Array<Int> using toTypedArray extension method like so:

val array = intArrayOf(5, 3, 0, 2, 4, 1, 0, 5, 2, 3, 1, 4).toTypedArray()
shellSort(array)

Or as @KirillRakhman suggested create a boxed version directly:

shellSort(arrayOf(5, 3, 0, 2, 4, 1, 0, 5, 2, 3, 1, 4))

Upvotes: 7

Tamas Hegedus
Tamas Hegedus

Reputation: 29946

This line

shellSort(arrayOf(array))

does not cast IntArray array to a regular Array<Integer>, but wraps it in a singleton array of type Array<IntArray>. Use IntArray.toTypedArray() to convert it to a generic array, as @miensol suggested.

Upvotes: 2

Related Questions