Kotlin Collections – Maps

Using Maps in Kotlin.

fun main() {
    // Use 'to' to map the key to the value. Don't really need to state Type as is inferred by Kotlin
    val immutableMap = mapOf(1 to Car("green", "Toyota", 2015), 2 to Car("red", "Ford", 2016), 3 to Car("silver", "Honda", 2013))

    println(immutableMap.javaClass) // Returns java.util.LinkedHashMap
    println(immutableMap) // Returns keys and instance references as we haven't overwritten toString() or made a data class

    val mutableMap = mutableMapOf<String, Car>("John's car" to Car("red", "Range Rover", 2010), "Jane's car" to Car("blue", "Hyundai", 2012))
    println(mutableMap.javaClass) // Also returns java.util.LinkedHashMap. Kotlin prefers this as it has a predictable iteration order - allows easy conversion from List to Set to Map
    println(mutableMap)
    mutableMap.put("Mary's car", Car("red", "Corvette", 1965)) // Don't use the 'to' keyword when putting


    val mutableMap2 = hashMapOf<String, Car>("John's car" to Car("red", "Range Rover", 2010), "Jane's car" to Car("blue", "Hyundai", 2012)) // If you want a hashMap instead of a LinkedHashMap
    println(mutableMap2)
    mutableMap2.put("Mary's car", Car("red", "Corvette", 1965)) // Don't use the 'to' keyword when putting

    val pair = Pair(10, "ten") // Create a Pair
//    val firstValue = pair.first // Access 1st value
//    val secondValue = pair.second // Access 2nd value
    val (firstValue, secondValue) = pair // The Kotlin way - destructuring declaration. We've distributed the public values into different variables
    println(firstValue)
    println(secondValue)

    // If we want to iterate over the mutableMap:
    for ((k, v) in mutableMap) { // Destructuring declaration - only works in classes that have implemented component functions. To do this with custom class see next code block (Pair is a data class so has this included):
        println(k)
        println(v)
    }

    val car = Car("blue", "Corvette", 1959)
    val (colour, model, year) = car
    println("Colour: $colour Model: $model Year: $year")

    val car2 = Car2("blue", "Corvette", 1959)
    val (colour2, model2, year2) = car2
    println("Colour: $colour2 Model: $model2 Year: $year2")
}

class Car(val colour: String, val model: String, val year: Int) {

    operator fun component1() = colour // Implementing component functions. Only works if properties are public
    operator fun component2() = model
    operator fun component3() = year

}

data class Car2(val colour: String, val model: String, val year: Int) // No need to implement component functions as data classes already have them