Using Lists in Kotlin.
// Kotlin often uses Java Collections, but even then you can do more with them
// Completely interoperable with Java
// You can operate on an immutable Collection (add, remove items), but the result will be a brand new instance
// All Collections take a generic type and all the read-only interfaces are covariant (e.g. you can assign a List of BigDecimal to a List of Any)
// If you look at the Collections declaration you will see it only has e.g. isEmpty() and contains(), and is covariant <out E>. MutableCollection adds add(), remove() etc and is not covariant <E>. Cannot assign mutable Collection of e.g. BigDecimal to Any.
// List and Set Collections. Array is considered a Collection but is in kotlin package, not kotlin/Collections. Doesn't implement any Collection interfaces.
fun main() {
val strings = listOf("spring", "summer", "autumn", "winter") // This is wrong - produces List not ArrayList
println(strings.javaClass) // returns java.utils.Arrays$ArrayList - can't add or remove anything but can change one of the elements (.set), therefore mutable.
// Kotlin makes it immutable by not having any functions in the Kotlin List interface that can change the ArrayList
// However, there are ways around this if the List is passed to Java code so need to be aware!
val mutableSeasons = strings.toMutableList() // Creates a mutable List from an immmutable one
mutableSeasons.add("Another season")
println(mutableSeasons)
val emptyList = emptyList<String>()
println(emptyList.javaClass) // returns kotlin.collections.EmptyList. Not much you can do with this list so no need for Java class. Maybe you would return it where your function would usually return an immutable List.
// println(emptyList[0]) // Still lets you call get() resulting in IndexOutOfBoundsException. Check if empty first if potentially receiving an empty List.
val notnullList = listOfNotNull("hello", null, "goodbye") // You can use this technique to filter out any potential null results...
println(notnullList) // ... returning a List of non-null values
//We can get a standard Java ArrayList by specifically requesting it:
val arrayList = arrayListOf(1, 2, 4)
println(arrayList.javaClass) // Mutable List of class java.util.ArrayList
val mutableList = mutableListOf<Int>(1, 2, 3)
println(mutableList.javaClass) // Also mutable List of class java.util.ArrayList
println(mutableList[2]) // We can use [] to get and set items
mutableList[1] = 20
println(mutableList)
mutableList.set(0, 40) // Or we can use the getters and setters
mutableList.get(2)
val array = arrayOf("black", "white", "green")
val colourlist = listOf(array) // Creates a List with one Array item
println(colourlist) // We probably would have wanted an array of 3 elements, so:
val actualColourList = listOf(*array)
println(actualColourList)// or even easier...
val actualColourList2 = array.toList()
println(actualColourList2)
val ints = intArrayOf(1, 2, 3)
println(ints.toList()) // Converts a Kotlin Array to a primitive array for passing to Java
// To manipulate Lists:
println(strings.last()) // Get the last element
println(strings.asReversed()) // Print them out backwards
// The long way:
if (strings.size > 5) {
println(strings[5])
}
// The Kotlin way:
println(strings.getOrNull(5)) // Will get element 5 or return null
val ints1 = listOf(1, 2, 3, 4, 5)
println(ints1.max()) // Gets largest value
println(actualColourList.zip(strings)) // Only creates pairs for as long as pairs can be made
val mergedLists = listOf(actualColourList, strings) // Creates a List of 2 Lists
println(mergedLists)
val combinedList = actualColourList + strings // Concatenates the 2 Lists
println(combinedList)
// To combine two lists and exclude duplicates:
val strings2 = listOf("spring", "summer", "autumn", "summer", "winter")
val colourList2 = listOf("black", "white", "red", "black", "red")
val noDupsList = colourList2.union(strings2)
println(noDupsList)
// To remove duplicates without having to combine the List with anything else:
val noDupColours = colourList2.distinct() // Returns a new list
println(noDupColours)
}