Top 10 Kotlin Stack Overflow Questions (Google I/O Extended 2018 Budapest)

Top 10 Kotlin Stack Overflow Questions (Google I/O Extended 2018 Budapest)

A selection of some of the most frequent questions about Kotlin on Stack Overflow, asked, answered and explained. Something in there for everyone, from beginners to experts.

Talk recording (Hungarian): https://youtu.be/-UMqYBoUlJc?t=4h7m38s

4047c64e3a1e2f81addd4ba675ddc451?s=128

Marton Braun

May 08, 2018
Tweet

Transcript

  1. 11.

    Array<Int> vs IntArray Array<Int> Integer[] IntArray int[] val intArray: IntArray

    = intArrayOf(1, 2, 3, 4, 5) val arrayOfInts: Array<Int> = arrayOf(1, 2, 3, 4, 5)
  2. 15.

    Array<Int> vs IntArray • IntArray  Avoids boxing  Easier

    to initialize val intArray = IntArray(10) val arrayOfInts = Array<Int>(5) { i -> i * 2 }
  3. 16.

    Array<Int> vs IntArray • IntArray  Avoids boxing  Easier

    to initialize • Array<Int> val intArray = IntArray(10) val arrayOfInts = Array<Int>(5) { i -> i * 2 }
  4. 17.

    Array<Int> vs IntArray • IntArray  Avoids boxing  Easier

    to initialize • Array<Int>  Might be required by an API val intArray = IntArray(10) val arrayOfInts = Array<Int>(5) { i -> i * 2 }
  5. 18.

    Array<Int> vs IntArray • IntArray  Avoids boxing  Easier

    to initialize • Array<Int>  Might be required by an API  Can store nullable values val intArray = IntArray(10) val arrayOfInts = Array<Int>(5) { i -> i * 2 } val notPeople: Array<Person?> = arrayOfNulls<Person>(13)
  6. 24.

    Iterable vs Sequence  Eager evaluation Iterable java.lang.Iterable val people:

    List<Person> = getPeople() val allowedEntrance = people .filter { it.age >= 21 } .map { it.name } .take(5)
  7. 26.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  8. 27.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  9. 28.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  10. 29.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  11. 30.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  12. 31.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  13. 32.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  14. 33.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  15. 34.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  16. 35.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  17. 36.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  18. 37.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  19. 38.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  20. 39.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  21. 40.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  22. 41.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  23. 42.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  24. 43.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  25. 44.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  26. 45.

    val people: List<Person> = getPeople() val allowedEntrance = people .filter

    { it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
  27. 49.

    Iterable vs Sequence Sequence  Lazy evaluation val people: List<Person>

    = getPeople() val allowedEntrance = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  28. 50.

    Iterable vs Sequence Sequence  Lazy evaluation val people: List<Person>

    = getPeople() val allowedEntrance = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  29. 52.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  30. 53.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  31. 54.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  32. 55.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  33. 56.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  34. 57.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  35. 58.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  36. 59.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  37. 60.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  38. 61.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  39. 62.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  40. 63.

    Iterable vs Sequence val allowedEntrance = people.asSequence() .filter { it.age

    >= 21 } .map { it.name } .take(5) .toList() val people: List<Person> = getPeople() val allowedEntrance = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  41. 64.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  42. 65.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  43. 66.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  44. 67.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  45. 68.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  46. 69.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  47. 70.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  48. 71.

    Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

    = people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
  49. 76.

    Iterable vs Sequence • Iterable  Use by default 

    Usually the best choice • Sequence
  50. 77.

    Iterable vs Sequence • Iterable  Use by default 

    Usually the best choice • Sequence  To handle an infinite number of elements
  51. 78.

    Iterable vs Sequence • Iterable  Use by default 

    Usually the best choice • Sequence  To handle an infinite number of elements  For huge collections, judiciously
  52. 79.

    Iterable vs Sequence • Iterable  Use by default 

    Usually the best choice • Sequence  To handle an infinite number of elements  For huge collections, judiciously • Stream
  53. 80.

    Iterable vs Sequence • Iterable  Use by default 

    Usually the best choice • Sequence  To handle an infinite number of elements  For huge collections, judiciously • Stream  When interoperating with Java
  54. 82.
  55. 84.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) }
  56. 85.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) }
  57. 86.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) } for (i in args.indices) { println(args[i]) }
  58. 87.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) } for (i in args.indices) { println(args[i]) } for (arg in args) { println(arg) }
  59. 88.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) } for (i in args.indices) { println(args[i]) } for (arg in args) { println(arg) } args.forEach { arg -> println(arg) }
  60. 89.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) } for (i in args.indices) { println(args[i]) } for (arg in args) { println(arg) } args.forEach { arg -> println(arg) }
  61. 90.

    Iteration for (i in 0..args.size - 1) { println(args[i]) }

    for (i in 0..args.lastIndex) { println(args[i]) } for (i in 0 until args.size) { println(args[i]) } for (i in args.indices) { println(args[i]) } for (arg in args) { println(arg) } args.forEach { arg -> println(arg) }
  62. 94.

    SAM conversions public interface OnClickListener { void onClick(Button button); }

    public class Button { public void setListener(OnClickListener listener) { ... } }
  63. 97.

    SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

    { println("Clicked!") } }) button.setListener { println("Clicked!") }
  64. 98.

    SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

    { println("Clicked!") } }) button.setListener { println("Clicked!") }
  65. 99.

    SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

    { println("Clicked!") } }) button.setListener { button: Button? -> println("Clicked!") }
  66. 101.

    SAM conversions #1 button.setListener { object : OnClickListener { override

    fun onClick(button: Button) { println("Clicked!") } }) }
  67. 102.

    SAM conversions #1 button.setListener { object : OnClickListener { override

    fun onClick(button: Button) { println("Clicked!") } }) }
  68. 103.

    SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

    Button?) { object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
  69. 104.

    SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

    Button?) { val listener = object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
  70. 105.

    SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

    Button?) { val listener = object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) listener.onClick(...) } })
  71. 106.

    SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

    Button?) { object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
  72. 107.

    SAM conversions #1 button.setListener { object : OnClickListener { override

    fun onClick(button: Button) { println("Clicked!") } }) }
  73. 108.

    SAM conversions #1 button.setListener { object : OnClickListener { override

    fun onClick(button: Button) { println("Clicked!") } }) } button.setListener { fun onClick(button: Button) { println("Clicked!") } }
  74. 113.

    SAM conversions #2 public interface OnClickListener { boolean onClick(Button button);

    } button.setListener { println("Clicked!") } Kotlin: Type mismatch: inferred type is Unit but Boolean was expected
  75. 114.
  76. 115.
  77. 118.

    Replacing statics class Foo { companion object { fun x()

    { ... } } fun y() { ... } } Foo.x()
  78. 119.

    Replacing statics class Foo { companion object { fun x()

    { ... } } fun y() { ... } } object Foo { fun x() { ... } } Foo.x() Foo.x()
  79. 120.

    Replacing statics class Foo { companion object { fun x()

    { ... } } fun y() { ... } } object Foo { fun x() { ... } } fun x() { ... } Foo.x() Foo.x() x()
  80. 121.

    Replacing statics class Foo { companion object { fun x()

    { ... } } fun y() { ... } } object Foo { fun x() { ... } } fun x() { ... } Foo.x() Foo.x() x()
  81. 122.

    Function declaration reference Declaration Kotlin usage Java usage Companion object

    Foo.f() Foo.Companion.f(); Companion object with @JvmStatic Foo.f() Foo.f(); Object Foo.f() Foo.INSTANCE.f(); Object with @JvmStatic Foo.f() Foo.f(); Top level function f() UtilKt.f(); Top level function with @JvmName* f() Util.f(); * With the @JvmName annotation on the file use-site target
  82. 123.

    Variable declaration reference Declaration Kotlin usage Java usage Companion object

    X.x X.Companion.getX(); Companion object with @JvmStatic X.x X.getX(); Companion object with @JvmField X.x X.x; Companion object with const X.x X.x; Object X.x X.INSTANCE.getX(); Object with @JvmStatic X.x X.getX(); Object with @JvmField X.x X.x; Object with const X.x X.x; Top level variable x ConstKt.getX(); Top level variable with @JvmField x ConstKt.x; Top level variable with const x ConstKt.x; Top level variable with @JvmName* x Const.getX(); Top level variable with @JvmName* and @JvmField x Const.x; Top level variable with @JvmName* and const x Const.x; * With the @JvmName annotation on the file use-site target
  83. 125.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { if (toy != null) { toy.chew() } } }
  84. 126.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { if (toy != null) { toy.chew() } } } Kotlin: Smart cast to 'Toy' is impossible, because 'toy' is a mutable property that could have been changed by this time
  85. 127.

    Smart casts on mutable properties class Dog(val toy: Toy? =

    null) { fun play() { if (toy != null) { toy.chew() } } }
  86. 128.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { if (toy != null) { toy.chew() } } }
  87. 129.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { val _toy = toy if (_toy != null) { _toy.chew() } } }
  88. 130.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { toy?.let { it.chew() } } }
  89. 131.
  90. 132.

    Smart casts on mutable properties class Dog(var toy: Toy? =

    null) { fun play() { toy?.let { it.chew() it.chew() it.chew() } } }
  91. 134.
  92. 136.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() }
  93. 137.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date?
  94. 138.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } WeekDay Date?
  95. 139.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date WeekDay Date?
  96. 140.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date
  97. 141.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date date as Date
  98. 142.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date date as Date throw NullPointerException()
  99. 143.

    null!! class Episode { var airdate: Date = null!! }

    fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date
  100. 148.

    Platform types in overrides How do I choose the right

    type when overriding Java methods?
  101. 151.

    Platform types in overrides public interface OnClickListener { void onClick(Button

    button); } class KtListener : OnClickListener { override fun onClick(button: Button?): Unit { val name = button?.name ?: "Unknown button" println("Clicked ${name}") } }
  102. 152.

    Platform types in overrides public interface OnClickListener { void onClick(Button

    button); } class KtListener : OnClickListener { override fun onClick(button: Button?): Unit { val name = button?.name ?: "Unknown button" println("Clicked ${name}") } }
  103. 153.

    Platform types in overrides public interface OnClickListener { void onClick(Button

    button); } class KtListener : OnClickListener { override fun onClick(button: Button?): Unit { val name = button?.name ?: "Unknown button" println("Clicked ${name}") } }
  104. 154.

    Platform types in overrides public interface OnClickListener { void onClick(Button

    button); } class KtListener : OnClickListener { override fun onClick(button: Button): Unit { val name = button.name println("Clicked ${name}") } }
  105. 157.

    Import aliases package com.example.code fun indent(str: String) : String {

    ... } package com.example.square fun indent(str: String) : String { ... }
  106. 158.

    Import aliases package com.example.code fun indent(str: String) : String {

    ... } package com.example.square fun indent(str: String) : String { ... } import com.example.code.indent indent("hello") com.example.square.indent("world")
  107. 159.

    Import aliases package com.example.code fun String.indent() : String { ...

    } package com.example.square fun String.indent() : String { ... }
  108. 160.

    Import aliases package com.example.code fun String.indent() : String { ...

    } package com.example.square fun String.indent() : String { ... } import com.example.code.indent "hello".indent() "world".indent()
  109. 161.

    Import aliases package com.example.code fun String.indent() : String { ...

    } package com.example.square fun String.indent() : String { ... } import com.example.code.indent as indent4 import com.example.square.indent as indent2 "hello".indent4() "world".indent2()
  110. 162.

    Import aliases import java.util.Date as UtilDate import java.sql.Date as SqlDate

    fun matches(date1: UtilDate, date2: SqlDate): Boolean { ... }
  111. 166.

    Recap • 1. Array<Int> vs IntArray • 2. Iterable vs

    Sequence • 3. Iteration • 4. SAM conversions • 5. Replacing statics • 6. Smart casts on mutable properties • 7. null!! • 8. Platform types in overrides • 9. Import aliases • 10. Kotlin vs Java for Android development
  112. 167.

    References • Top 10 Kotlin Stack Overflow questions, article series

     https://zsmb.co/top-10-kotlin-stack-overflow-questions-1/ • Kotlin tag on Stack Overflow  https://stackoverflow.com/questions/tagged/kotlin