4

I will be reading data from a byte stream. Are the indices given by Kotlin to an array generation function (as described in https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html) guaranteed to be called in order, ascending from zero?

The Array.kt file is under builtins so I'm at a loss as to where to find the actual code.

4
  • 2
    Related: stackoverflow.com/questions/56091276/… Commented Jun 30, 2019 at 2:21
  • 1
    I found this after digging around, but I wouldn't count on it. Commented Jun 30, 2019 at 2:29
  • 1
    Are you compiling to bytecode or javascript? I imagine there could be diffrences in these implementations. If you compile to javascript there should be .js file with lots of built-in code. I'd reccomend taking a look there. Commented Jun 30, 2019 at 17:55
  • @Hullburg good question. The answer is: I don't know. I'm writing an open source library. Commented Jul 1, 2019 at 16:59

2 Answers 2

4

Take a look at the source code for Array:

public inline constructor(size: Int, init: (Int) -> T)

The init parameter is a function that takes an int (the index for a specific item), to which it expects a return value of type T, which the array consists of.

As the other answers have shown by examples, these are called in order, because it's the "natural" way of doing it. If you don't get what I mean, think about the implementation alternatives:

for (i in 0..size) {
    this.addToArray(init(i));
}

Alternatively:

for (i in (size - 1)..0 {
    this.addToArray(init(i));
}

Compared to:

val indices = mutableListOf<Int>()
while (indices.size != size) {
    val i = random.nextInt(size); 
    if (i !in indices) {
        indices.add(i);
        this.addToArray(init(i));
    }
}

While we can't see the source code for the constructor, the examples show in the other answers alone show they cannot be using a random approach. Applying the code from the first answer, mathematically speaking, the odds of using random and getting 0-49 printed out in order are extremely low.

Additionally, this is backed up by an answer here. The resulting compiled Java code creates a for-loop going from 0 to size. For the JVM, assuming they don't change the implementation, you can assume it'll go from 0 to size. But whether it goes from 0 to size or from size to 0, you can always reverse it if you don't like the order.

If you need to be 100% sure it goes from 0 to size, or if the implementation changes, you can do something like:

var a = (0 until 10).step(1).toList().toTypedArray()

Which, in this case, yields an array with the numbers 0-9.

If you want objects, or otherwise alter the object, you can add a .map {} before the list creation. That being said, this is an overkill alternative as long as the init function works as you'd expect.

And you can always confirm by decompiling the code using IntelliJ, Android Studio, some other IDE, or a decompiler of your choice. But regardless of the implementation, they'll always end up in order - so you don't need to worry about that. The only thing they oculd possibly change is the order the init function is called in, but it'll still end up in the same order in the resulting array.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your thorough answer. You're right, there doesn't seem to be a good reason for doing it in any other way than sequentially. But that doesn't mean that somebody won't come up with something -- for example, somebody might decide to parallelize index enumeration. This is why the API makes no guarantee, and why I can't rely on sequential initialization.
good answer Olivia! congrats for your good first contribution! you've got my +1
0

That does seem to be the case. Code:

fun main() {
    val x = Array(50) {println(it)}
}

5 Comments

Can you link to the <init> code?
I made a hyperlink. Does clicking it not work? Oh in here? ok.
I mean the Kotlin Array::init code itself -- somewhere there must be a file called Array.kt.
I see. I do not know where to find that, sorry.
That doesn't guarantee it will always be called in order, in future versions, and on all platforms. Unless the documentation says so, I wouldn't write code that relies on the order.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.