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

 

Add Android Architecture Component Dependencies

To add the desired elements of Android Jetpack to your app. These will need to be updated as the version numbers increment.

Use the following in your build.gradle: Futures

dependencies {
    def futures_version = "1.0.0-alpha02"

    implementation "androidx.concurrent:concurrent-futures:$futures_version"
}

Lifecycle AndroidX

dependencies {
    def lifecycle_version = "2.0.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // use -ktx for Kotlin
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // use kapt for Kotlin
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // use -ktx for Kotlin

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}

Lifecycle pre-AndroidX

dependencies {
    def lifecycle_version = "1.1.1"

    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // use -ktx for Kotlin
    // alternatively - just LiveData
    implementation "android.arch.lifecycle:livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData).
    //     Support library depends on this lightweight import
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"

    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
    // alternately - if using Java8, use the following instead of compiler
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"

    // optional - Test helpers for LiveData
    testImplementation "android.arch.core:core-testing:$lifecycle_version"
}

Room AndroidX

dependencies {
    def room_version = "2.1.0-alpha03"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version" // use kapt for Kotlin

    // optional - RxJava support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // optional - Coroutines support for Room
    implementation "androidx.room:room-coroutines:$room_version"

    // Test helpers
    testImplementation "androidx.room:room-testing:$room_version"
}

Room pre-AndroidX

dependencies {
    def room_version = "1.1.1"

    implementation "android.arch.persistence.room:runtime:$room_version"
    annotationProcessor "android.arch.persistence.room:compiler:$room_version" // use kapt for Kotlin

    // optional - RxJava support for Room
    implementation "android.arch.persistence.room:rxjava2:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "android.arch.persistence.room:guava:$room_version"

    // Test helpers
    testImplementation "android.arch.persistence.room:testing:$room_version"
}

Paging AndroidX

dependencies {
    def paging_version = "2.1.0-rc01"

    implementation "androidx.paging:paging-runtime:$paging_version" // use -ktx for Kotlin

    // alternatively - without Android dependencies for testing
    testImplementation "androidx.paging:paging-common:$paging_version" // use -ktx for Kotlin

    // optional - RxJava support
    implementation "androidx.paging:paging-rxjava2:$paging_version" // use -ktx for Kotlin
}

Paging pre-AndroidX

dependencies {
    def paging_version = "1.0.0"

    implementation "android.arch.paging:runtime:$paging_version"

    // alternatively - without Android dependencies for testing
    testImplementation "android.arch.paging:common:$paging_version"

    // optional - RxJava support
    implementation "android.arch.paging:rxjava2:$paging_version"
}

Navigation

dependencies {
    def nav_version = "1.0.0-alpha09"

    implementation "android.arch.navigation:navigation-fragment:$nav_version" // use -ktx for Kotlin
    implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin
}

Work Manager

dependencies {
    def work_version = "1.0.0-beta02"

    implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin+Coroutines

    // optional - RxJava2 support
    implementation "android.arch.work:work-rxjava2:$work_version"

    // optional - Test helpers
    androidTestImplementation "android.arch.work:work-testing:$work_version"
}

See more here