Slide 1

Slide 1 text

Kirill Suslov Explore Kotlin.Collections API

Slide 2

Slide 2 text

- friend “Lol! This is an intern interview question in JavaScript ”

Slide 3

Slide 3 text

Less Code is (usually) Better*

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

1. Helps making the code much more concise 2. Part of kotlin-stdlib 3. Built on top of Java Collections API Kotlin.Collections highlights

Slide 6

Slide 6 text

Collection Mutable Read-only Immutable

Slide 7

Slide 7 text

Collection Mutable Read-only • MutableList • MutableSet • MutableMap • List • Set • Map

Slide 8

Slide 8 text

Neat stuff

Slide 9

Slide 9 text

data class Movie( val title: String, val releaseDate: Date, val genre: String, val averageRating: Double) Model

Slide 10

Slide 10 text

val madMax = Movie("Mad Max", "2015-05-13".toDate(), "action", 7.3) val dunkirk = Movie("Dunkirk", "2017-07-19".toDate(), "action", 7.6) val birdman = Movie("Birdman", "2014-10-17".toDate(), "drama", 7.4) val titanic = Movie("Titanik", "1997-12-19".toDate(), "romance", 7.6) val lamb = Movie("The Silence of the Lambs", "1991-01-30".toDate(), "thriller", 8.1) val nemo = Movie("Finding Nemo", "2003-05-30".toDate(), "animation", 7.7) Some movies

Slide 11

Slide 11 text

fun String.toDate(): Date { val formatter = SimpleDateFormat("yyyy-mm-dd") return formatter.parse(this) } Extension function

Slide 12

Slide 12 text

Creation functions Neat stuff. Part 1

Slide 13

Slide 13 text

List and Mutable List val movieList = listOf(madMax, dunkirk, birdman, titanic, lamb, nemo) val movieMutableList = mutableListOf(madMax, dunkirk, birdman, titanic, lamb, nemo)

Slide 14

Slide 14 text

Set and Mutable Set val movieSet = setOf(madMax, dunkirk, birdman, titanic, lamb, nemo) val movieMutableSet = mutableSetOf(madMax, dunkirk, birdman, titanic, lamb, nemo) Map and Mutable Map val movieMap = mapOf(madMax.title to madMax, dunkirk.title to dunkirk) val movieMutableMap = mutableMapOf(madMax.title to madMax, dunkirk.title to dunkirk) // PROTIP madMax.title to madMax == Pair(madMax.title, madMax)

Slide 15

Slide 15 text

Aggregate functions Neat stuff. Part 2

Slide 16

Slide 16 text

Count() movieList.count() // Count: 6 // movieList.count() == movieList.size

Slide 17

Slide 17 text

MaxBy() movieList.maxBy { it.averageRating } // Max rating: The Silence of the Lambs, 8.1 Note: max() if element is a number

Slide 18

Slide 18 text

MinBy() movieList.minBy { it.averageRating } // Min rating: Mad Max, 7.3 Note: min() if element is a number

Slide 19

Slide 19 text

Average() arrayOf(7.3, 7.6, 7.4, 7.6, 8.1, 7.7).average() // Average: 7.616666666666667

Slide 20

Slide 20 text

Sum() arrayOf(7.3, 7.6, 7.4, 7.6, 8.1, 7.7).sum() // Sum: 45.7 movieList.sumByDouble { it.averageRating }

Slide 21

Slide 21 text

Mode() and Median() aren’t there

Slide 22

Slide 22 text

Search functions Neat stuff. Part 3

Slide 23

Slide 23 text

First() movieList.first { it.averageRating < 7.5 } // First: Mad Max movieList.first { it.averageRating < 3.0 } // NoSuchElementException

Slide 24

Slide 24 text

Find() movieList.find { it.averageRating < 7.5 } // First: Mad Max movieList.find { it.averageRating < 3.0 } // First: null // movieList.find() == movieList.firstOrNull()

Slide 25

Slide 25 text

Last() movieList.last { it.averageRating < 7.5 } // First: Birdman movieList.last { it.averageRating < 3.0 } // NoSuchElementException

Slide 26

Slide 26 text

FindLast() movieList.findLast { it.averageRating < 7.5 } // First: Birdman movieList.findLast { it.averageRating < 3.0 } // First: null // movieList.findLast() == movieList.lastOrNull()

Slide 27

Slide 27 text

Single() movieList.single { it.averageRating == 7.7 } // Single: Finding Nemo movieList.single { it.averageRating == 7.6 } // IllegalArgumentException

Slide 28

Slide 28 text

SingleOrNull() movieList.singleOrNull { it.averageRating == 7.7 } // Single: Finding Nemo movieList.singleOrNull { it.averageRating == 7.6 } // Single: null

Slide 29

Slide 29 text

Filter functions Neat stuff. Part 4

Slide 30

Slide 30 text

Filter() movieList.filter { it.averageRating > 7.5 } // Better than 7.5: // [Dunkirk, Titanik, The Silence of the Lambs, Finding Nemo]

Slide 31

Slide 31 text

FilterNot(), FilterNotNull() movieList.filterNot { it.averageRating > 7.5 } // Not better than 7.5: [Mad Max, Birdman] movieList.filterNotNull() // Kinda useless here

Slide 32

Slide 32 text

FilterTo(), filterNotTo() val listToFilterInto = mutableListOf() movieList.filterTo(listToFilterInto, { it.averageRating > 7.5 }) // Better than 7.5: [Dunkirk, Titanik, The Silence of the Lambs, Finding Nemo] movieList.filterNotTo(listToFilterInto, { it.averageRating > 7.5 }) // Not better than 7.5: [Mad Max, Birdman] movieList.filterNotNullTo(listToFilterInto) // Kinda useless here

Slide 33

Slide 33 text

FilterIndexed() movieList.filterIndexed { index, movie -> index.even() } // Even Indexed: [Mad Max, Birdman, The Silence of the Lambs]

Slide 34

Slide 34 text

Transform functions Neat stuff. Part 5

Slide 35

Slide 35 text

Map() movieList.map { it.title } // [Mad Max, Dunkirk, Birdman, Titanik, // The Silence of the Lambs, Finding Nemo] movieList.mapIndexed { index, movie -> index to movie.title } // [(0, Mad Max), (1, Dunkirk), (2, Birdman), // (3, Titanik), (4, The Silence of the Lambs), (5, Finding Nemo)]

Slide 36

Slide 36 text

val madMax = Movie("Mad Max", "2015-05-13".toDate(), listOf("action"), 7.3) val dunkirk = Movie("Dunkirk", "2017-07-19".toDate(), listOf("action", "drama"), 7.6) val birdman = Movie("Birdman", "2014-10-17".toDate(), listOf("drama"), 7.4) val titanic = Movie("Titanik", "1997-12-19".toDate(), listOf("romance"), 7.6) val lamb = Movie("The Silence of the Lambs", "1991-01-30".toDate(), listOf("thriller"), 8.1) val nemo = Movie("Finding Nemo", "2003-05-30".toDate(), listOf("animation"), 7.7) Add some changes

Slide 37

Slide 37 text

FlatMap() movieList.map { it.genre } // [[action], [action, drama], [drama], [romance], [thriller], [animation]] movieList.flatMap { it.genre } // [action, action, drama, drama, romance, thriller, animation]

Slide 38

Slide 38 text

Distinct() // [action, action, drama, drama, romance, thriller, animation] genreList.distinct() // [action, drama, romance, thriller, animation]

Slide 39

Slide 39 text

Associate(), AssociateBy() movieList.associate { it.title to it.averageRating } movieList.associateBy({ it.title }, { it.averageRating }) // {Mad Max=7.3, Dunkirk=7.6, Birdman=7.4, Titanik=7.6, // The Silence of the Lambs=8.1, Finding Nemo=7.7}

Slide 40

Slide 40 text

GroupBy() movieList.groupBy({ it.genre }, { it.title }) // {action=[Mad Max, Dunkirk], drama=[Birdman], romance=[Titanik], // thriller=[The Silence of the Lambs], animation=[Finding Nemo]}

Slide 41

Slide 41 text

Neat stuff. Final Part

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

val average = movieList.filter { it.genre == "action" } .map { it.averageRating } .average() // 7.449999999999999 var count = 0 var total = 0.0 for (movie in movieList) { if (movie.genre == "action") { count++ total += movie.averageRating } } val average = total / count // 7.449999999999999 Collection API Old school

Slide 44

Slide 44 text

9 lines of old fashioned code 3 lines of neatness Comparison Slide

Slide 45

Slide 45 text

Chart Title Lines 0 2 5 7 9 Java style Collection API

Slide 46

Slide 46 text

val averagePerCategory = movieList .groupBy { it.genre } .mapValues { it.value .map { it.averageRating } .average() } /* {action=7.449999999999999, drama=7.4, romance=7.6, thriller=8.1, animation=7.7} */ More of Collection API

Slide 47

Slide 47 text

How to start

Slide 48

Slide 48 text

1. Android Studio hints

Slide 49

Slide 49 text

2. Read source code (_Collections.kt)

Slide 50

Slide 50 text

3. Challenge yourself

Slide 51

Slide 51 text

shopify.com/ careers