46

I tried these in Kotlin REPL

var listA = listOf(null ,null)
var listB = [null, null]

The first line works fine as expected. On displaying listA I get:

[null, null]

The second line throws the following error:

error: cannot use 'Nothing?' as reified type parameter
var listB = [null,null]
            ^
error: unsupported [Collection literals outside of annotations]
var listB = [null,null]
            ^
error: unsupported [Array<Nothing> in return type is illegal]
var listB = [null,null]
            ^

When I try the same with non null types, i.e.

var listC = [1,2]

I get this error:

error: unsupported [Collection literals outside of annotations]
var listC = [1,2]
            ^

I'm new to Kotlin. Can someone please explain what is going on here?

Shreyas
  • 593
  • 1
  • 4
  • 9

5 Answers5

46

From the Kotlin documentation on Collections:

Kotlin does not have dedicated syntax constructs for creating lists or sets. Use methods from the standard library, such as listOf(), mutableListOf(), setOf(), mutableSetOf().

There are no list literals currently for code outside of annotations.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
42

As @Carcigenicate pointed out, there is not syntax for [null, null].
However, Kotlin does have some handy methods for handling lists and arrays.

Lists

  • listOf()

    Creates a new read-only List.

  • listOfNotNull()

    Basically the same as listOf(), but without null values. Even empty strings are skipped.

  • arrayListOf()

    Creates an ArrayList. This time you can modify (add/remove) elements.

  • mutableListOf()

    Behaves like arrayListOf(). Actually, mutableListOf() internally uses ArrayLists. Read more

Arrays

  • arrayOf()

    This creates an array, which is very different to most languages you know. Instead of syntax structures like {1, 2, 3} or [1, 2, 3] you have functions in Kotlin. You also get functions for typed array:

    • booleanArrayOf()
    • doubleArrayOf()
    • charArrayOf()
    • ...

One exception are annotations, which explains your compiler error [Collection literals outside of annotations]:

@MyAnnotation(arguments = [1, 2, 3])

However, this could change in the future as discussed here.


While working with arrays, it is important to know the return types those functions are creating. As an example: Array<Int> is an Integer[] under the hood, while IntArray is a primitive int[] when targeting the JVM.
null
  • 575
  • 4
  • 12
11

So for the case of mutable lists, you can declare an empty String one with: val list: MutableList<String> = mutableListOf(). If you wanted an immutable list then you could use val like so: val list: List<String> = listOf("x", "y", "z").

Also note, that you should consider your use case for using val or var. Mutability of a list pertains to values within the list itself, where as val and var are for the variable. You can reassign the list if you use var but not val (similar to final of Java)

For the sake of clarity, as an example, mutable lists can have elements added an removed after their initialisation, while immutable cannot.

Immutable Lists Docs

Mutable List Docs

Miniman
  • 221
  • 1
  • 4
  • 16
2

You get [null, null] because that's how toString() happens to be defined in java.util.AbstractCollection and listOf creates a java.util.ArrayList which inherits this implementation.

The errors you get are because there is a place in Kotlin where this syntax happens to work: annotation parameters. So the parser understands it. But it creates arrays, not lists, and so your code wouldn't compile even if the syntax wasn't limited to annotations.

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

Yes this is not the correct syntax for creating List with Kotlin. Here is an example of List and MutableList(with write operations) and some of the operations you can do on them:

List

val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")

MutableList

val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
numbers.removeAt(1)
numbers[0] = 0
numbers.shuffle()
println(numbers)
aabiro
  • 3,842
  • 2
  • 23
  • 36