Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Use the Force (of Kotlin Stdlib)

GDG SPb
September 30, 2017

Use the Force (of Kotlin Stdlib)

В деталях рассмотрим почти все возможности Kotlin Stdlib

GDG SPb

September 30, 2017
Tweet

More Decks by GDG SPb

Other Decks in Programming

Transcript

  1. Inline Functions fun nthFibonacciNumber(n: Int): Int { require (n >=

    0, "'n' must be non-negative, but was $n.") // ... } fun require(value: Boolean, message: String) { if (!value) throw IllegalArgumentException(message) }
  2. Inline Functions fun nthFibonacciNumber(n: Int): Int { require (n >=

    0) { "'n' must be non-negative, but was $n." } // ... } fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
  3. Inline Functions fun nthFibonacciNumber(n: Int): Int { require (n >=

    0) { "'n' must be non-negative, but was $n." } // ... } inline fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
  4. Inline Functions fun nthFibonacciNumber(n: Int): Int { if (!(n >=

    0)) throw IllegalArgumentException("'n' must be non-negative, but was $n.") // ... } inline fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
  5. Inline Functions. Preconditions // Throws AssertionError inline fun assert(value: Boolean)

    inline fun assert(value: Boolean, lazyMessage: () -> Any) // Throws IllegalArgumentException inline fun require(value: Boolean) inline fun require(value: Boolean, lazyMessage: () -> Any) inline fun requireNotNull(value: T?): T inline fun requireNotNull(value: T?, lazyMessage: () -> Any): T // Throws IllegalStateException inline fun check(value: Boolean) inline fun check(value: Boolean, lazyMessage: () -> Any) inline fun checkNotNull(value: T?): T inline fun checkNotNull(value: T?, lazyMessage: () -> Any): T // Throws IllegalStateException immediately inline fun error(message: Any)
  6. Extension Functions fun String.toInt(): Int = Integer.parseInt(this) public static final

    int toInt(@NotNull String $receiver) { return Integer.parseInt($receiver); }
  7. Extension Functions. Number Conversions inline fun String.toByte(radix: Int = 10):

    Byte inline fun String.toShort(radix: Int = 10): Short inline fun String.toInt(radix: Int = 10): Int inline fun String.toLong(radix: Int = 10): Long inline fun String.toFloat(): Float inline fun String.toDouble(): Double inline fun String.toBoolean(): Boolean inline fun Byte.toString(radix: Int): String inline fun Short.toString(radix: Int): String inline fun Int.toString(radix: Int): String inline fun Long.toString(radix: Int): String fun String.toByteOrNull(radix: Int = 10): Byte? fun String.toShortOrNull(radix: Int = 10): Short? fun String.toIntOrNull(radix: Int = 10): Int? fun String.toLongOrNull(radix: Int = 10): Long? fun String.toFloatOrNull(): Float? fun String.toDoubleOrNull(): Double?
  8. Operator Overloading operator fun plus(other: P): R // a +

    b, a += b operator fun minus(other: P): R // a - b, a -= b operator fun times(other: P): R // a * b, a *= b operator fun div(other: P): R // a / b, a /= b operator fun rem(other: P): R // a % b, a %= b operator fun plusAssign(other: P): Unit // a += b operator fun minusAssign(other: P): Unit // a -= b operator fun timesAssign(other: P): Unit // a *= b operator fun divAssign(other: P): Unit // a /= b operator fun remAssign(other: P): Unit // a %= b operator fun unaryPlus(): R // +a operator fun unaryMinus(): R // -a operator fun inc(): MyType // a++, ++a operator fun dec(): MyType // a--, --a operator fun not(): R // !a operator fun compareTo(other: P): Int // a >= b, a > b, a < b, a <= b operator fun equals(other: Any?): Boolean // a == b, a != b operator fun contains(other: P): Boolean // b in a, b !in a
  9. inline operator fun BigInteger.plus(other: BigInteger) : BigInteger inline operator fun

    BigInteger.minus(other: BigInteger) : BigInteger inline operator fun BigInteger.times(other: BigInteger) : BigInteger inline operator fun BigInteger.div(other: BigInteger) : BigInteger inline operator fun BigInteger.rem(other: BigInteger) : BigInteger inline operator fun BigInteger.unaryMinus() : BigInteger Operator Overloading. Big Numbers
  10. inline operator fun BigInteger.plus(other: BigInteger) : BigInteger inline operator fun

    BigInteger.minus(other: BigInteger) : BigInteger inline operator fun BigInteger.times(other: BigInteger) : BigInteger inline operator fun BigInteger.div(other: BigInteger) : BigInteger inline operator fun BigInteger.rem(other: BigInteger) : BigInteger inline operator fun BigInteger.unaryMinus() : BigInteger val enormousNumber = BigInteger("12345678909876543210") * BigInteger("42") Operator Overloading. Big Numbers
  11. inline operator fun BigInteger.plus(other: BigInteger) : BigInteger inline operator fun

    BigInteger.minus(other: BigInteger) : BigInteger inline operator fun BigInteger.times(other: BigInteger) : BigInteger inline operator fun BigInteger.div(other: BigInteger) : BigInteger inline operator fun BigInteger.rem(other: BigInteger) : BigInteger inline operator fun BigInteger.unaryMinus() : BigInteger val enormousNumber = BigInteger("12345678909876543210") * BigInteger("42") val enormousNumberV2 = -enormousNumber Operator Overloading. Big Numbers
  12. inline operator fun BigInteger.plus(other: BigInteger) : BigInteger inline operator fun

    BigInteger.minus(other: BigInteger) : BigInteger inline operator fun BigInteger.times(other: BigInteger) : BigInteger inline operator fun BigInteger.div(other: BigInteger) : BigInteger inline operator fun BigInteger.rem(other: BigInteger) : BigInteger inline operator fun BigInteger.unaryMinus() : BigInteger val enormousNumber = BigInteger("12345678909876543210") * BigInteger("42") val enormousNumberV2 = -enormousNumber if (BigInteger("42") > BigInteger.TEN) { println("Welcome, Captain Obvious!") } Operator Overloading. Big Numbers
  13. Operator Overloading operator fun invoke(p1: P1, ..., pN: PN): R

    // a(p1, ..., pN) operator fun get(p1: P1, ..., pN: PN): R // a[p1, ..., pN] operator fun set(p1: P1, ..., pN: PN, t: T): Unit // a[p1, ..., pN] = t operator fun rangeTo(other: P): R // a..b operator fun component1(): R // val myVal = MyType() operator fun componentN(): R // val (c1, ..., cN) = myVal operator fun iterator(): PseudoIterator // val myVal = MyType() // for (i in myVal) { class PseudoIterator { // ... operator fun next(): R // } operator fun hasNext(): Boolean }
  14. Operator Overloading operator fun invoke(p1: P1, ..., pN: PN): R

    // a(p1, ..., pN) operator fun get(p1: P1, ..., pN: PN): R // a[p1, ..., pN] operator fun set(p1: P1, ..., pN: PN, t: T): Unit // a[p1, ..., pN] = t operator fun rangeTo(other: P): R // a..b operator fun component1(): R // val myVal = MyType() operator fun componentN(): R // val (c1, ..., cN) = myVal operator fun iterator(): PseudoIterator // val myVal = MyType() // for (i in myVal) { class PseudoIterator { // ... operator fun next(): R // } operator fun hasNext(): Boolean }
  15. Operator Overloading. Iterators class MyType(private var value: Int) { private

    var divider: Int init { val pow10 = if (value == 0) 1 else Math.log10(value.toDouble()).toInt() divider = Math.pow(10.0, pow10.toDouble()).toInt() } operator fun next(): Int { val res = value / divider value %= divider divider /= 10 return res } operator fun hasNext() = divider > 0 }
  16. Function Literals with Receiver Map<String, String> headers = new ArrayMap<String,

    String>() {{ this.put("User-Agent", userAgent); if (userManager.isLoggedIn) { this.put("Authorization", userManager.accessToken); } }};
  17. Function Literals with Receiver inline fun <T> T.apply(block: T.() ->

    Unit): T { this.block(); return this } val headers = ArrayMap<String, String>().apply { this.put("User-Agent", userAgent) if (userManager.isLoggedIn) { this.put("Authorization", userManager.accessToken) } }
  18. Function Literals with Receiver inline fun <T> T.apply(block: T.() ->

    Unit): T { this.block(); return this } val headers = ArrayMap<String, String>().apply { put("User-Agent", userAgent) if (userManager.isLoggedIn) { put("Authorization", userManager.accessToken) } }
  19. var user: User? fun renderUser() { if (user != null)

    { nameView.text = user.name ageView.text = user.age } } Function Literals with Receiver
  20. var user: User? fun renderUser() { if (user != null)

    { nameView.text = user.name ageView.text = user.age } } Error! Smart cast to ‘User’ is impossible, because ‘user’ is a mutable property that could have been changed by this time. Function Literals with Receiver
  21. var user: User? fun renderUser() { val usr = user

    if (usr != null) { nameView.text = usr.name ageView.text = usr.age } } Function Literals with Receiver
  22. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { val usr = user if (usr != null) { nameView.text = usr.name ageView.text = usr.age } } Function Literals with Receiver
  23. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { user?.let { usr -> nameView.text = usr.name ageView.text = usr.age } } Function Literals with Receiver
  24. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { user?.let { nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
  25. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
  26. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null and nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
  27. inline fun <T, R> T.let(block: (T) -> R): R =

    block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null and it was already read into local val nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
  28. Function Literals with Receiver inline fun <T, R> T.let(block: (T)

    -> R): R = block(this) fun fetchData() { getResponse()?.let { // result of ‘getResponse()’ was already read/delivered/calculated logResponse(it) saveData(parseData(it)) } }
  29. Function Literals with Receiver inline fun <T> T.apply(block: T.() ->

    Unit): T { block(); return this } inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this } inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() inline fun <T, R> T.let(block: (T) -> R): R = block(this) inline fun <T, R> T.run(block: T.() -> R): R = block() inline fun <R> run(block: () -> R): R = block()
  30. Reified Type Parameters Map<Integer, String> int2Str = newMap(); <K,V> Map<K,

    V> newMap() { return new HashMap<K, V>(); } String[] strArr = newArray(42) <T> T[] newArray(int size) { return new T[size]; }
  31. Reified Type Parameters Map<Integer, String> int2Str = newMap(); <K,V> Map<K,

    V> newMap() { return new HashMap<K, V>(); } String[] strArr = newArray(42) <T> T[] newArray(int size) { return new T[size]; }
  32. Reified Type Parameters inline fun <reified T> arrayOfNulls(size: Int): Array<T?>

    = T[size] fun fill(dest: Array<String?>) { // ... } fill(arrayOfNulls(10))
  33. Reified Type Parameters. Arrays inline fun <reified T> arrayOfNulls(size: Int):

    Array<T?> // = T[size] inline fun <reified T> arrayOf(vararg elements: T): Array<T> // = T[] { elements } inline fun <reified T> emptyArray(): Array<T> // = T[0]
  34. Kotlin features Stdlib is based on • Inline Functions •

    Extension Functions • Operator Overloading • Function Literals with Receiver • Reified type parameters
  35. Collections fun <T> emptyList(): List<T> = EmptyList fun <T> listOf(element:

    T): List<T> = Collections.singletonList(element) fun <T> listOf([vararg elements: T]): List<T> fun <T> mutableListOf([vararg elements: T]): MutableList<T> // ArrayList fun <T> arrayListOf([vararg elements: T]): ArrayList<T> fun <T: Any> listOfNotNull(element: T?): List<T> fun <T: Any> listOfNotNull(vararg elements: T?): List<T> inline fun <T> List(size: Int, init: (index: Int) -> T): List<T> inline fun <T> MutableList(size: Int, init: (index: Int) -> T): MutableList<T>
  36. fun <T> emptySet(): Set<T> = EmptySet fun <T> setOf(element: T):

    Set<T> = Collections.singleton(element) fun <T> setOf([vararg elements: T]): Set<T> fun <T> mutableSetOf([vararg elements: T]): MutableSet<T> // LinkedHashSet fun <T> hashSetOf([vararg elements: T]): HashSet<T> fun <T> linkedSetOf([vararg elements: T]): LinkedHashSet<T> fun <T> sortedSetOf([comparator: Comparator<in T>,] vararg elements: T): TreeSet<T> Collections
  37. Collections val <T> List<T>.lastIndex: Int get() = this.size - 1

    inline fun <T> Collection<T>?.orEmpty(): Collection<T> inline fun <T> List<T>?.orEmpty(): List<T>
  38. Collections inline operator fun <T> List<T>.component1(): T inline operator fun

    <T> List<T>.component5(): T operator fun <T> Iterable<T>.contains(element: T): Boolean operator fun <T> Collection<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.minus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T>
  39. Collections inline operator fun <T> List<T>.component1(): T inline operator fun

    <T> List<T>.component5(): T operator fun <T> Iterable<T>.contains(element: T): Boolean operator fun <T> Collection<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.minus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> val (s1, s2, s3, s4, s5) = listOf<String>(...)
  40. Collections inline operator fun <T> List<T>.component1(): T inline operator fun

    <T> List<T>.component5(): T operator fun <T> Iterable<T>.contains(element: T): Boolean operator fun <T> Collection<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.minus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> if ("Jan" in months) { // ... }
  41. Collections inline operator fun <T> List<T>.component1(): T inline operator fun

    <T> List<T>.component5(): T operator fun <T> Iterable<T>.contains(element: T): Boolean operator fun <T> Collection<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.minus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> androidLanguagesList += "Kotlin"
  42. Collections. Search inline fun <T> Iterable<T>.first([predicate: (T) -> Boolean]): T

    inline fun <T> Iterable<T>.last([predicate: (T) -> Boolean]): T inline fun <T> Iterable<T>.firstOrNull([predicate: (T) -> Boolean]): T? inline fun <T> Iterable<T>.lastOrNull([predicate: (T) -> Boolean]): T? inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? // = firstOrNull() inline fun <T> Iterable<T>.findLast(predicate: (T) -> Boolean): T? // = lastOrNull() inline fun <T> Iterable<T>.single([predicate: (T) -> Boolean]): T inline fun <T> Iterable<T>.singleOrNull([predicate: (T) -> Boolean]): T
  43. Collections. Search fun <T> Iterable<T>.indexOf(element: T): Int fun <T> Iterable<T>.lastIndexOf(element:

    T): Int inline fun <T> Iterable<T>.indexOfFirst(predicate: (T) -> Boolean): Int inline fun <T> Iterable<T>.indexOfLast(predicate: (T) -> Boolean): Int fun <T> List<T>.binarySearch([from: Int, to: Int,] comparison: (T) -> Int): Int fun <T: Comparable<T>> List<T?>.binarySearch(elem: T?, [from: Int, to: Int]): Int fun <T> List<T>. binarySearch(elem: T, comparator: Comparator<in T>, [from: Int, to: Int]): Int inline fun <T, K: Comparable<K>> List<T>. binarySearchBy(key: K?, [from: Int, to: Int,] selector: (T) -> K?): Int
  44. Collections. Filtering inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T>

    inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T> fun <T: Any> Iterable<T?>.filterNotNull(): List<T> inline fun <T, C: MutableCollection<in T>> Iterable<T>. filterTo(dest: C, predicate: (T) -> Boolean): C filterIndexedTo(dest: C, predicate: (index: Int, T) -> Boolean): C filterNotTo(dest: C, predicate: (T) -> Boolean): C fun <C: MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(dest: C): C fun <R> Iterable<*>.filterIsInstance(klass: Class<R>): List<R> inline fun <reified R> Iterable<*>.filterIsInstance(): List<R> fun <C: MutableCollection<in R>, R> Iterable<*>. filterIsInstanceTo(dest: C, klass: Class<R>): C inline fun <reified R, C: MutableCollection<in R>> Iterable<*>. filterIsInstanceTo(dest: C): C
  45. Collections. Filtering fun <T> MutableIterable<T>.removeAll(cond: (T) -> Boolean): Boolean //

    filterNotInPlace() fun <T> MutableIterable<T>.retainAll(cond: (T) -> Boolean): Boolean // filterInPlace() fun <T> MutableCollection<in T>.removeAll(Array<out T>|Iterable<T>|Sequence<T>): Boolean fun <T> MutableCollection<in T>.retainAll(Array<out T>|Iterable<T>|Sequence<T>): Boolean
  46. Collections. Filtering fun <T> Iterable<T>.take(n: Int): List<T> fun <T> List<T>.takeLast(n:

    Int): List<T> inline fun <T> Iterable<T>.takeWhile(predicate: (T) -> Boolean): List<T> inline fun <T> List<T>.takeLastWhile(predicate: (T) -> Boolean): List<T> fun <T> Iterable<T>.drop(n: Int): List<T> fun <T> List<T>.dropLast(n: Int): List<T> inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T>
  47. Collections. Sorting fun <T: Comparable<T>> Iterable<T>.sorted(): List<T> fun <T: Comparable<T>>

    Iterable<T>.sortedDescending(): List<T> fun <T: Comparable<T>> MutableList<T>.sort(): Unit fun <T: Comparable<T>> MutableList<T>.sortDescending(): Unit inline fun <T, R: Comparable<R>> Iterable<T>.sortedBy(selector: (T) -> R?): List<T> inline fun <T, R: Comparable<R>> Iterable<T>.sortedByDescending(selector: (T) -> R?): List<T> inline fun <T, R: Comparable<R>> MutableList<T>.sortBy(selector: (T) -> R?): Unit inline fun <T, R: Comparable<R>> MutableList<T>.sortByDescending(selector: (T) -> R?): Unit fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit
  48. Collections. Reversing & Slicing fun <T> Iterable<T>.reversed(): List<T> fun <T>

    MutableList<T>.reverse(): Unit fun <T> List<T>.asReversed(): List<T> fun <T> MutableList<T>.asReversed(): MutableList<T> fun <T> List<T>.slice(indices: IntRange): List<T> fun <T> List<T>.slice(indices: Iterable<Int>): List<T>
  49. Collections. Mapping inline fun <T, K, V> Iterable<T>. associate(transform: (T)

    -> Pair<K, V>): Map<K, V> associateBy(keySelector: (T) -> K, [valueTransform: (T) -> V]): Map<K, V> inline fun <T, K, V, M: MutableMap<in K, in V>> Iterable<T>. associateTo(dest: M, transform: (T) -> Pair<K, V>): M associateByTo(dest: M, keySelector: (T) -> K, [valueTransform: (T) -> V]): M
  50. Collections. Mapping inline fun <T, R> Iterable<T>. map(transform: (T) ->

    R): List<R> mapIndexed(transform: (index: Int, T) -> R): List<R> inline fun <T, R: Any> Iterable<T>. mapNotNull(transform: (T) -> R?): List<R> mapIndexedNotNull(transform: (index: Int, T) -> R?): List<R> inline fun <T, R, C: MutableCollection<in R>> Iterable<T>. mapTo(dest: C, transform: (T) -> R): C mapIndexedTo(dest: C, transform: (index: Int, T) -> R): C inline fun <T, R: Any, C: MutableCollection<in R>> Iterable<T>. mapNotNullTo(dest: C, transform: (T) -> R?): C mapIndexedNotNullTo(dest: C, transform: (index: Int, T) -> R?): C
  51. Collections. Mapping & Grouping inline fun <T> Iterable<T>.forEach(action: (T) ->

    Unit): Unit inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit inline fun <T, C: Iterable<T>> C.onEach(action: (T) -> Unit): C inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> inline fun <T, R, C: MutableCollection<in R>> Iterable<T>. flatMapTo(dest: C, transform: (T) -> Iterable<R>): C inline fun <T, K, V> Iterable<T>. groupBy(keySelector: (T) -> K, [valueTransform: (T) -> V]): Map<K, List<V>> inline fun <T, K, V, M: MutableMap<in K, MutableList<V>>> Iterable<T>. groupByTo(dest: M, keySelector: (T) -> K, [valueTransform: (T) -> V]): M inline fun <T, K> Iterable<T>.groupingBy(keySelector: (T) -> K): Grouping<T, K>
  52. Collections. Misc fun <T> Iterable<T>.distinct(): List<T> inline fun <T, K>

    Iterable<T>.distinctBy(selector: (T) -> K): List<T> fun <T> Iterable<Iterable<T>>.flatten(): List<T> infix fun <T, R> Iterable<T>.zip(Array<out R>|Iterable<R>): List<Pair<T, R>> inline fun <T, R, V> Iterable<T>. zip(Array<out R>|Iterable<R>, transform: (a: T, b: R) -> V): List<V> fun <T, R> Iterable<Pair<T, R>>.unzip(): Pair<List<T>, List<R>> inline fun <T> Iterable<T>.partition(predicate: (T) -> Boolean): Pair<List<T>, List<T>> infix fun <T> Iterable<T>.intersect(other: Iterable<T>): Set<T> infix fun <T> Iterable<T>.subtract(other: Iterable<T>): Set<T> infix fun <T> Iterable<T>.union(other: Iterable<T>): Set<T>
  53. Collections. Aggregation fun Iterable<Int>.average(): Double fun Iterable<Int>.sum(): Int inline fun

    <T> Iterable<T>.sumBy(selector: (T) -> Int): Int inline fun <T> Iterable<T>.sumByDouble(selector: (T) -> Double): Double inline fun <T> Iterable<T>.count([predicate: (T) -> Boolean]): Int fun <T: Comparable<T>> Iterable<T>.max(): T? fun <T: Comparable<T>> Iterable<T>.min(): T? inline fun <T, R: Comparable<R>> Iterable<T>.maxBy(selector: (T) -> R): T? inline fun <T, R: Comparable<R>> Iterable<T>.minBy(selector: (T) -> R): T? fun <T> Iterable<T>.maxWith(comparator: Comparator<in T>): T? fun <T> Iterable<T>.minWith(comparator: Comparator<in T>): T? inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean inline fun <T> Iterable<T>.any([predicate: (T) -> Boolean]): Boolean inline fun <T> Iterable<T>.none([predicate: (T) -> Boolean]): Boolean
  54. Collections. Folding & Reducing inline fun <T, R> Iterable<T>. fold(initial:

    R, operation: (acc: R, T) -> R): R foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R inline fun <T, R> List<T>. foldRight(initial: R, operation: (T, acc: R) -> R): R foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R inline fun <S, T: S> Iterable<T>. reduce(operation: (acc: S, T) -> S): S reduceIndexed(operation: (index: Int, acc: S, T) -> S): S inline fun <S, T: S> List<T>. reduceRight(operation: (T, acc: S) -> S): S reduceRightIndexed(operation: (index: Int, T, acc: S) -> S): S
  55. Collections. ToString fun <T> Iterable<T>.joinToString( separator: CharSequence = ", ",

    prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String fun <T, A : Appendable> Iterable<T>.joinTo( buffer: A, sep: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): A
  56. Here goes all the same stuff for Arrays, Sequences and

    CharSequences... ...if applicable
  57. Collections. Conversion fun <T, C: MutableCollection<in T>> Iterable<T>.toCollection(dest: C): C

    fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
  58. Collections. Conversion fun <T, C: MutableCollection<in T>> Iterable<T>.toCollection(dest: C): C

    fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
  59. Collections. Conversion fun <T, C: MutableCollection<in T>> Iterable<T>.toCollection(dest: C): C

    fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
  60. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) Collections
  61. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() Collections
  62. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } Collections
  63. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title in user.movies } Collections
  64. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title in user.movies } .groupBy { it.genre } Collections
  65. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } Collections
  66. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } Collections
  67. data class User(val birthday: Date, val movies: List<String>) data class

    Movie(val title: String, val airDate: Date, val posterUrl: String, val likesCount: Int, val genre: Genre) repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Collections
  68. repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title

    in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Collections
  69. repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title

    in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .joinToString(separator = "\n", prefix = "My movie preferences by genre:\n") { (genre, count, _) -> "$genre movies watched: $count" } Collections
  70. fun <T> emptySequence(): Sequence<T> = EmptySequence fun <T> sequenceOf(vararg elements:

    T): Sequence<T> fun <T: Any> generateSequence(nextFunction: () -> T?): Sequence<T> generateSequence(seed: T?, nextFunction: (T) -> T?): Sequence<T> generateSequence(seedFunction: () -> T?, nextFunction: (T) -> T?): Sequence<T> inline fun <T> Sequence(iterator: () -> Iterator<T>): Sequence<T> fun <T> Sequence<T>.constrainOnce(): Sequence<T> Sequences
  71. fun genFibonacciSequence(): Sequence<Int> = generateSequence(0 to 1) { (prev, next)

    -> next to (prev + next) }.map { (next, _) -> next } Sequences
  72. fun genFibonacciSequence(): Sequence<Int> = generateSequence(0 to 1) { (prev, next)

    -> next to (prev + next) }.map { (next, _) -> next } genFibonacciSequence() .takeWhile { it < 100 } .forEach(::println) Sequences
  73. fun genFibonacciSequence(): Sequence<Int> = generateSequence(0 to 1) { (prev, next)

    -> next to (prev + next) }.map { (next, _) -> next } genFibonacciSequence() .takeWhile { it < 100 } .forEach(::println) // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 Sequences
  74. repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title

    in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Sequences
  75. repo.getMovies() .filter { it.airDate > user.birthday } .filter { it.title

    in user.movies } .groupBy { it.genre } .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Sequences
  76. repo.getMovies() .asSequence() .filter { it.airDate > user.birthday } .filter {

    it.title in user.movies } .groupBy { it.genre } .asSequence() .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Sequences
  77. repo.getMovies() .asSequence() .filter { it.airDate > user.birthday } .filter {

    it.title in user.movies } .groupBy { it.genre } .asSequence() .map { (genre, movies) -> Triple(genre, movies.size, movies.maxBy { it.likesCount }) } .sortedByDescending { (_, count, _) -> count } .forEach { (genre, count, movie) -> plotHistogram(label = genre, value = count, tooltipImageUrl = movie?.posterUrl) } Sequences
  78. fun <K, V> emptyMap(): Map<K, V> = EmptyMap fun <K,

    V> mapOf(p: Pair<K, V>): Map<K, V> = Collections.singletonMap(p.first, p.second) fun <K, V> mapOf([vararg pairs: Pair<K, V>]): Map<K, V> fun <K, V> mutableMapOf([vararg pairs: Pair<K, V>]): MutableMap<K, V> // LinkedHashMap fun <K, V> hashMapOf([vararg pairs: Pair<K, V>]): HashMap<K, V> fun <K, V> linkedMapOf([vararg pairs: Pair<K, V>]): LinkedHashMap<K, V> fun <K: Comparable<K>, V> sortedMapOf(vararg pairs: Pair<K, V>): SortedMap<K, V> inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V Maps
  79. fun <K, V> emptyMap(): Map<K, V> = EmptyMap fun <K,

    V> mapOf(p: Pair<K, V>): Map<K, V> = Collections.singletonMap(p.first, p.second) fun <K, V> mapOf([vararg pairs: Pair<K, V>]): Map<K, V> fun <K, V> mutableMapOf([vararg pairs: Pair<K, V>]): MutableMap<K, V> // LinkedHashMap fun <K, V> hashMapOf([vararg pairs: Pair<K, V>]): HashMap<K, V> fun <K, V> linkedMapOf([vararg pairs: Pair<K, V>]): LinkedHashMap<K, V> fun <K: Comparable<K>, V> sortedMapOf(vararg pairs: Pair<K, V>): SortedMap<K, V> inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V Maps
  80. inline fun <K, V> Map<out K, V>. filterKeys(predicate: (K) ->

    Boolean): Map<K, V> filterValues(predicate: (V) -> Boolean): Map<K, V> inline fun <K, V, R> Map<out K, V>. mapKeys(transform: (Map.Entry<K, V>) -> R): Map<R, V> mapValues(transform: (Map.Entry<K, V>) -> R): Map<K, R> Maps. Extra
  81. Maps fun wordCount(list: List<String>): Map<String, Int> { val map =

    mutableMapOf<String, Int>() for (item in list) { if (item !in map) { map[item] = 0 } map[item] = map[item] + 1 } return map }
  82. Maps fun wordCount(list: List<String>): Map<String, Int> { val map =

    mutableMapOf<String, Int>() for (item in list) { if (item !in map) { map[item] = 0 } map[item] = map[item] + 1 } return map } Error! Operator plus is not allowed on a nullable receiver.
  83. Maps fun wordCount(list: List<String>): Map<String, Int> { val map =

    mutableMapOf<String, Int>() for (item in list) { if (item !in map) { map[item] = 0 } map[item] = map[item]!! + 1 } return map }
  84. Maps fun wordCount(list: List<String>): Map<String, Int> { val map =

    mutableMapOf<String, Int>() for (item in list) { map[item] = (map[item] ?: 0) + 1 } return map }
  85. Maps fun wordCount(list: List<String>): Map<String, Int> { val map =

    mutableMapOf<String, Int>() for (item in list) { map[item] = map.getOrElse(item) { 0 } + 1 } return map }
  86. Maps with Default fun <K, V> Map<K, V>.withDefault(defaultValue: (key: K)

    -> V): Map<K, V> Warning! Does not change Map.get() semantics! Use Map.getValue() fun <K, V> Map<K, V>.getValue(key: K): V
  87. Maps with Default fun wordCount(list: List<String>): Map<String, Int> { val

    map = mutableMapOf<String, Int>().withDefault { 0 } for (item in list) { map[item] = map.getValue(item) + 1 } return map }
  88. inline fun <T, K> Iterable<T>.groupingBy(keySelector: (T) -> K): Grouping<T, K>

    interface Grouping<T, out K> { fun sourceIterator(): Iterator<T> fun keyOf(element: T): K } Grouping
  89. Grouping inline fun <T, K> Iterable<T>.groupingBy(keySelector: (T) -> K): Grouping<T,

    K> interface Grouping<T, out K> { fun sourceIterator(): Iterator<T> fun keyOf(element: T): K } inline fun <T, K, R> Grouping<T, K>. aggregate(op: (key: K, accumulator: R?, elem: T, first: Boolean) -> R): Map<K, R>
  90. Grouping fun wordCount(list: List<String>): Map<String, Int> { return list .groupingBy

    { word -> word } .aggregate { key, acc, elem, first -> (acc ?: 0) + 1 } }
  91. Grouping fun wordCount(list: List<String>): Map<String, Int> = list.groupingBy { it

    } .aggregate { _, acc, _, _ -> (acc ?: 0) + 1 } fun <T, K> Grouping<T, K>.eachCount(): Map<K, Int>
  92. Grouping fun wordCount(list: List<String>): Map<String, Int> = list.groupingBy { it

    }.eachCount() fun <T, K> Grouping<T, K>.eachCount(): Map<K, Int>
  93. Grouping fun wordCount(list: List<String>): Map<String, Int> = list.groupingBy { it

    }.eachCount() fun wordCount(list: List<String>): Map<String, Int> { val map = mutableMapOf<String, Int>() for (item in list) { if (item !in map) { map[item] = 0 } map[item] = map[item]!! + 1 } return map }
  94. Grouping inline fun <T, K, R> Grouping<T, K>. fold(initialValue: R,

    operation: (accumulator: R, element: T) -> R): Map<K, R> fold(initialValueSelector: (key: K, element: T) -> R, operation: (key: K, accumulator: R, element: T) -> R): Map<K, R> inline fun <S, T: S, K> Grouping<T, K>. reduce(operation: (key: K, accumulator: S, element: T) -> S): Map<K, S>
  95. Comparisons fun <T: Comparable<T>> maxOf(a: T, b: T, [c: T]):

    T fun <T: Comparable<T>> minOf(a: T, b: T, [c: T]): T // + variants for primitive numbers inline fun <T: Comparable<T>> nullsFirst(): Comparator<T?> inline fun <T: Comparable<T>> nullsLast(): Comparator<T?> fun <T: Any> nullsFirst(comparator: Comparator<in T>): Comparator<T?> fun <T: Any> nullsLast(comparator: Comparator<in T>): Comparator<T?> fun <T: Comparable<T>> naturalOrder(): Comparator<T> fun <T: Comparable<T>> reverseOrder(): Comparator<T> fun <T> Comparator<T>.reversed(): Comparator<T>
  96. Comparisons fun <T> compareBy(vararg selectors: (T) -> Comparable<*>?): Comparator<T> inline

    fun <T> compareBy(selector: (T) -> Comparable<*>?): Comparator<T> inline fun <T, K> compareBy(Comparator<in K>, selector: (T) -> K): Comparator<T>
  97. Comparisons inline fun <T> Comparator<T>. thenComparator(comparison: (a: T, b: T)

    -> Int): Comparator<T> thenBy(selector: (T) -> Comparable<*>?): Comparator<T> thenByDescending(selector: (T) -> Comparable<*>?): Comparator<T> inline fun <T, K> Comparator<T>. thenBy(Comparator<in K>, selector: (T) -> K): Comparator<T> thenByDescending(Comparator<in K>, selector: (T) -> K): Comparator<T> infix fun <T> Comparator<T>. then(comparator: Comparator<in T>): Comparator<T> thenDescending(comparator: Comparator<in T>): Comparator<T>
  98. Comparisons data class Movie(val title: String, val airYear: Int, val

    posterUrl: String, val likesCount: Int, val genre: Genre, val actors: List<Actor>) enum class Genre { COMEDY, ACTION, DRAMA, DOCUMENTARY } getMovies() .sortedWith(movieComparator) .filterNot { it.title in user.movies } .take(100)
  99. Comparisons val movieComparator = compareBy<Movie>(Movie::airYear) .thenBy(Movie::likesCount) .thenByDescending { it.actors.size }

    val genreComparator = compareBy<Genre> { when (it) { Genre.ACTION -> 40 Genre.DOCUMENTARY -> 30 Genre.COMEDY -> 20 Genre.DRAMA -> 10 } }
  100. Comparisons val movieComparator = compareBy<Movie>(Movie::airYear) .thenBy(genreComparator) { it.genre } .thenBy(Movie::likesCount)

    .thenByDescending { it.actors.size } val genreComparator = compareBy<Genre> { when (it) { Genre.ACTION -> 40 Genre.DOCUMENTARY -> 30 Genre.COMEDY -> 20 Genre.DRAMA -> 10 } }
  101. Comparisons val movieComparator = compareBy<Movie>(Movie::airYear) .thenBy(genreComparator) { it.genre } .thenBy(Movie::likesCount)

    .thenByDescending { it.actors.size } .reversed() val genreComparator = compareBy<Genre> { when (it) { Genre.ACTION -> 40 Genre.DOCUMENTARY -> 30 Genre.COMEDY -> 20 Genre.DRAMA -> 10 } }
  102. Text fun String.capitalize(): String fun String.decapitalize(): String fun CharSequence.isBlank(): Boolean

    inline fun CharSequence?.isNullOrBlank(): Boolean inline fun CharSequence?.isNullOrEmpty(): Boolean // Farewell TextUtils.isEmpty() fun CharSequence. commonPrefixWith(other: CharSequence, [ignoreCase: Boolean]): String commonSuffixWith(other: CharSequence, [ignoreCase: Boolean]): String splitToSequence(vararg delimiters: String, [ignoreCase: Boolean, limit: Int]): Sequence<String> fun CharSequence.lineSequence(): Sequence<String>
  103. IO. Closeable inline fun <T : Closeable?, R> T.use(block: (T)

    -> R): R inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R
  104. IO. Closeable inline fun <T : Closeable?, R> T.use(block: (T)

    -> R): R inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R fun InputStream.readLines(): List<String> = BufferedReader(InputStreamReader(this)).use { val lines = arrayListOf<String>() var line = it.readLine() while (line != null) { lines += line line = it.readLine() } lines }
  105. IO. Byte Streams inline fun InputStream. buffered([bufferSize: Int]): BufferedInputStream reader([charset:

    Charset]): InputStreamReader bufferedReader([charset: Charset]): BufferedReader inline fun OutputStream. buffered([bufferSize: Int]): BufferedOutputStream writer([charset: Charset]): OutputStreamWriter bufferedWriter([charset: Charset]): BufferedWriter fun InputStream.copyTo(out: OutputStream, [bufferSize: Int]): Long
  106. inline fun Reader.buffered([bufferSize: Int]): BufferedReader inline fun Writer.buffered([bufferSize: Int]): BufferedWriter

    fun Reader.readText(): String fun Reader.readLines(): List<String> fun BufferedReader.lineSequence(): Sequence<String> inline fun <T> Reader.useLines(block: (Sequence<String>) -> T): T fun Reader.forEachLine(action: (String) -> Unit): Unit fun Reader.copyTo(out: Writer, [bufferSize: Int]): Long IO. Text Streams
  107. IO. Files inline fun File.inputStream(): FileInputStream inline fun File.outputStream(): FileOutputStream

    inline fun File.reader([charset: Charset]): InputStreamReader inline fun File.writer([charset: Charset]): OutputStreamWriter inline fun File.bufferedReader([charset: Charset, bufferSize: Int]): BufferedReader inline fun File.bufferedWriter([charset: Charset, bufferSize: Int]): BufferedWriter inline fun File.printWriter([charset: Charset]): PrintWriter
  108. IO. Files fun File.readBytes(): ByteArray fun File.writeBytes(array: ByteArray): Unit fun

    File.appendBytes(array: ByteArray): Unit fun File.readText([charset: Charset]): String fun File.writeText(text: String, [charset: Charset]): Unit fun File.appendText(text: String, [charset: Charset]): Unit fun File.readLines([charset: Charset]): List<String> inline fun <T> File.useLines([charset: Charset], block: (Sequence<String>) -> T): T fun File.forEachLine([charset: Charset], action: (String) -> Unit): Unit fun File.forEachBlock([blockSize: Int,] action: (buffer: ByteArray, bytesRead: Int) -> Unit): Unit
  109. IO. Files val wordCount = File("shakespeare.txt").useLines { it.flatMap { it.splitToSequence('

    ', ',', '.', '!', '?') } .map { it.toLowerCase() } .groupingBy { it } .eachCount() }
  110. IO. Files val wordCount = File("shakespeare.txt").useLines { it.flatMap { it.splitToSequence('

    ', ',', '.', '!', '?') } .map { it.toLowerCase() } .groupingBy { it } .eachCount() }
  111. IO. Files val wordCount = File("shakespeare.txt").bufferedReader().use { it.lineSequence().flatMap { it.splitToSequence('

    ', ',', '.', '!', '?') } .map { it.toLowerCase() } .groupingBy { it } .eachCount() }
  112. IO. Files val File.extension: String val File.invariantSeparatorsPath: String val File.nameWithoutExtension:

    String fun File.toRelativeString(base: File): String fun File.relativeTo(base: File): File fun File.relativeToOrSelf(base: File): File fun File.relativeToOrNull(base: File): File? fun File.resolve(relative: String|File): File fun File.resolveSibling(relative: String|File): File fun File.startsWith(other: String|File): Boolean fun File.endsWith(other: String|File): Boolean
  113. IO. Files fun createTempDir(prefix: String = "tmp", [suffix: String?, directory:

    File?]): File fun createTempFile(prefix: String = "tmp", [suffix: String?, directory: File?]): File fun File.copyTo(target: File, overwrite: Boolean = false, [bufferSize: Int]): File fun File.copyRecursively(target: File, overwrite: Boolean = false, [onError: (File, IOException) -> OnErrorAction]): Boolean fun File.deleteRecursively(): Boolean
  114. Goodies. Ranges fun processResponse(response: Response) = when (response.code) { in

    200..299 -> ok(response) in 400..499 -> clientError(response) in 500..599 -> serverError(response) else -> throw IllegalStateException("Bummer")
  115. Goodies. Ranges fun processResponse(response: Response) = when (response.code) { in

    200..299 -> ok(response) in 400..499 -> clientError(response) in 500..599 -> serverError(response) else -> throw IllegalStateException("Bummer") public static final int processResponse(@NotNull Response response) { int code = response.code(); int result; if (200 <= code && code <= 299) { result = ok(response); } else if (400 <= code && code <= 499) { result = clientError(response); } else if (500 <= code && code <= 599) { result = serverError(response); } else { throw new IllegalStateException("Bummer"); } }
  116. Goodies. Locks inline fun <T> Lock.withLock(action: () -> T): T

    inline fun <T> ReentrantReadWriteLock.read(action: () -> T): T inline fun <T> ReentrantReadWriteLock.write(action: () -> T): T
  117. Goodies. Locks inline fun <T> Lock.withLock(action: () -> T): T

    inline fun <T> ReentrantReadWriteLock.read(action: () -> T): T inline fun <T> ReentrantReadWriteLock.write(action: () -> T): T val dbLock = ReentrantReadWriteLock() dbLock.write { writeToDb(entity) }
  118. inline fun measureNanoTime(block: () -> Unit) : Long inline fun

    measureTimeMillis(block: () -> Unit) : Long Goodies. System
  119. inline fun measureNanoTime(block: () -> Unit) : Long inline fun

    measureTimeMillis(block: () -> Unit) : Long val saveTime = measureNanoTime { writeToDb(entity) } println("Saving is soo sloow ${saveTime}ns") Goodies. System
  120. Goodies. Targeting Java 8 fun <T> Stream<T>.toList(): List<T> fun <T>

    Stream<T>.asSequence(): Sequence<T> fun <T> Sequence<T>.asStream(): Stream<T>
  121. Takeaways • No big inline method bodies • Public API

    in public inline functions • Reified functions are not present in bytecode • Eager collection processing functions • Use Sequence • “as”/”to” prefix convention • Ranges optimisations
  122. Anko. What I bet you know inline fun <reified T:

    Activity> Context. startActivity(vararg params: Pair<String, Any>) inline fun <reified T: Any> Context. intentFor(vararg params: Pair<String, Any?>): Intent
  123. Anko. What I bet you know inline fun <reified T:

    Activity> Context. startActivity(vararg params: Pair<String, Any>) inline fun <reified T: Any> Context. intentFor(vararg params: Pair<String, Any?>): Intent fun Context. toast(message: Int) longToast(message: Int)
  124. Anko. What I bet you know inline fun <reified T:

    Activity> Context. startActivity(vararg params: Pair<String, Any>) inline fun <reified T: Any> Context. intentFor(vararg params: Pair<String, Any?>): Intent fun Context. toast(message: Int) longToast(message: Int) val Context. alarmManager: AlarmManager audioManager: AudioManager connectivityManager: ConnectivityManager notificationManager: NotificationManager layoutInflater: LayoutInflater vibrator: Vibrator // ...
  125. Anko. What else? Collections inline fun <T> List<T>. forEachByIndex(f: (T)

    -> Unit) forEachWithIndex(f: (Int, T) -> Unit) // + Reversed
  126. Anko. What else? Collections inline fun <T> List<T>. forEachByIndex(f: (T)

    -> Unit) forEachWithIndex(f: (Int, T) -> Unit) // + Reversed
  127. Anko. What else? Collections inline fun <T> List<T>. forEachByIndex(f: (T)

    -> Unit) forEachWithIndex(f: (Int, T) -> Unit) // + Reversed inline fun <T> SparseArray<T>. forEach(action: (Int, T) -> Unit) asSequence(): Sequence<T>
  128. Anko. What else? ViewGroup Iteration fun ViewGroup. forEachChild(action: (View) ->

    Unit) forEachChildWithIndex(action: (Int, View) -> Unit) firstChild(predicate: (View) -> Boolean): View
  129. Anko. What else? ViewGroup Iteration fun ViewGroup. forEachChild(action: (View) ->

    Unit) forEachChildWithIndex(action: (Int, View) -> Unit) firstChild(predicate: (View) -> Boolean): View
  130. Anko. What else? ViewGroup Iteration fun ViewGroup. forEachChild(action: (View) ->

    Unit) forEachChildWithIndex(action: (Int, View) -> Unit) firstChild(predicate: (View) -> Boolean): View fun View.childrenRecursiveSequence(): Sequence<View>
  131. Anko. What else? Configuration Helpers doFromSdk(Build.VERSION_CODES.M) { window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

    } configuration(uiMode = UiMode.CAR, nightMode = true) { schedulePlaySong("System Of A Down - Chop Suey!") }
  132. inline fun <reified T : View> Activity.find(@IdRes id: Int): T

    inline fun <reified T : View> Activity.findOptional(@IdRes id: Int): T? Anko. What else? ViewUtils
  133. inline fun <reified T : View> Activity.find(@IdRes id: Int): T

    inline fun <reified T : View> Activity.findOptional(@IdRes id: Int): T? val callBtn = findViewById(R.id.callBtn) as Button Anko. What else? ViewUtils
  134. inline fun <reified T : View> Activity.find(@IdRes id: Int): T

    inline fun <reified T : View> Activity.findOptional(@IdRes id: Int): T? val callBtn = findViewById(R.id.callBtn) as Button val callBtn = find<Button>(R.id.callBtn) Anko. What else? ViewUtils
  135. fun bundleOf(vararg params: Pair<String, Any>): Bundle fun showMap(location: LatLng, zoomLevel:

    Int) { val mapFragment = MapFragment().apply { arguments = bundleOf( EXTRA_LOCATION_KEY to location, EXTRA_ZOOM_KEY to zoomLevel ) } showFragment(mapFragment) } Anko. What else? Bundles
  136. fun <T: Fragment> T.withArguments(vararg params: Pair<String, Any>): T fun showMap(location:

    LatLng, zoomLevel: Int) { val mapFragment = MapFragment().withArguments( EXTRA_LOCATION_KEY to location, EXTRA_ZOOM_KEY to zoomLevel ) showFragment(mapFragment) } Anko. What else? Bundles
  137. What was left behind • Hidden costs of language constructs

    ◦ Exploring Kotlin’s hidden costs  series, https://goo.gl/Gh4uxK • @Jvm* annotations - Kotlin->Java interop ◦ Writing Java-friendly Kotlin code, Mobius https://goo.gl/mXedcb • @DslMarker ◦ Fantastic DSLs and Where to Find Them, https://goo.gl/vcGmmG • Different Annotation targets • Reflection • Coroutines ◦ Корутины в Kotlin - Роман Елизаров, https://goo.gl/wUWSpv