I’m updating a Java codebase to Kotlin. I’m stuck ...
# getting-started
a
I’m updating a Java codebase to Kotlin. I’m stuck on trying to update
Arrays.copyOfRange()
Copy code
fun copyData(
 codePointsWindow: IntArray,
 pointer: Int,
 dataLength: Int,
 read: Int,
): IntArray {
  return Arrays.copyOfRange(codePointsWindow, pointer, dataLength + read)
}
IntelliJ pops-up a warning, “Should be replaced with Kotlin function”, and provides a quickfix:
Copy code
return codePointsWindow.copyOfRange(pointer, dataLength + read)
However then a lot of tests fail with
Copy code
toIndex (11) is greater than size (0).
java.lang.IndexOutOfBoundsException: toIndex (11) is greater than size (0).
	at kotlin.collections.ArraysKt__ArraysJVMKt.copyOfRangeToIndexCheck(ArraysJVM.kt:49)
	at kotlin.collections.ArraysKt___ArraysJvmKt.copyOfRange(_ArraysJvm.kt:1859)
I’ve made an issue IDEA-320926 for the quickfix not producing equivalent code, but can someone help me with a suitable replacement for now?
I think the difference is that
Arrays.copyOfRange()
allows for the index to lie outside of the source array’s bounds, while Kotlin’s
copyOfRange()
performs a check
alright, this util function seems to work:
Copy code
/**
 * Like [IntArray.copyOfRange], but allows for [toIndex] to be out-of-bounds.
 */
private fun IntArray.copyOfRangeSafe(fromIndex: Int, toIndex: Int): IntArray =
    IntArray(toIndex - fromIndex) { getOrNull(fromIndex + it) ?: 0 }
thank for rubber ducking rubber duck , any further suggestions or refinements are welcome!
h
Or simpler:
Copy code
fun IntArray.copyOfRangeSafe(fromIndex: Int, toIndex: Int) =
    copyOfRange(fromIndex, toIndex.coerceAtMost(size))
a
that one fails if
fromIndex == toIndex
Copy code
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
h
😞 You're right. But I'd still prefer to fix the param ranges and use the
copyOfRange
function instead of doing the copying yourself.
a
me too!
h
is your source array empty? for me, fromIndex == toIndex works…
a
yeah, I think it might be
yeah, it is.
println(indices)
returns
0..-1
h
But yeah, what IntelliJ suggests definitely is not equivalent
I'd probably just use the Java method then.
a
the plan is to (eventually) convert to Kotlin Multiplatform, so it would have to be replaced at some point :)
k
toIndex.coerceAtMost(size)
will not work, because Java's
copyOfRange
guarantees the returned array will have size
toIndex - fromIndex
.
👌 1