Márton Braun
May 17, 2018
350

# Top 10 Kotlin Stack Overflow Questions (Kotlin Budapest User Group meetup - May)

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.

May 17, 2018

## Transcript

1. ### TOP 10 KOTLIN STACK OVERFLOW QUESTIONS Márton Szabolcs Braun zsmb.co

zsmb13 [email protected]

which one?

2, 3, 4, 5)
9. ### Array<Int> vs IntArray Array<Int> Integer[] IntArray val arrayOfInts: Array<Int> =

arrayOf(1, 2, 3, 4, 5)
10. ### Array<Int> vs IntArray Array<Int> Integer[] IntArray int[] val arrayOfInts: Array<Int>

= arrayOf(1, 2, 3, 4, 5)
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)

15. ### Array<Int> vs IntArray • IntArray  Avoids boxing  Easier

to initialize val intArray = IntArray(10) val arrayOfInts = Array<Int>(5) { i -> i * 2 }
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 }
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 }
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)

which one?

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)

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

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
27. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
28. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
29. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
30. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
31. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
32. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
33. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
34. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
35. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
36. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
37. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
38. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
39. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
40. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
41. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
42. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
43. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
44. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

{ it.age >= 21 } .map { it.name } .take(5) Iterable vs Sequence
45. ### val people: List<Person> = getPeople() val allowedEntrance = people .filter

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

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()
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()

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

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
53. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
54. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
55. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
56. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
57. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
58. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
59. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
60. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
61. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
62. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
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()
64. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
65. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
66. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
67. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
68. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
69. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
70. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

= people.asSequence() .filter { it.age >= 21 } .map { it.name } .take(5) .toList()
71. ### Iterable vs Sequence val people: List<Person> = getPeople() val allowedEntrance

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

74. ### Iterable vs Sequence Sequence  Lazy evaluation  Potentially infinite

generateSequence(1) { n -> n * 2 } .take(20) .forEach(::println)

78. ### Iterable vs Sequence • Iterable  Use by default 

Usually the best choice
79. ### Iterable vs Sequence • Iterable  Use by default 

Usually the best choice • Sequence
80. ### Iterable vs Sequence • Iterable  Use by default 

Usually the best choice • Sequence  To handle an infinite number of elements
81. ### Iterable vs Sequence • Iterable  Use by default 

Usually the best choice • Sequence  To handle an infinite number of elements  For huge collections, judiciously
82. ### Iterable vs Sequence • Iterable  Use by default 

Usually the best choice • Sequence  To handle an infinite number of elements  For huge collections, judiciously • Stream
83. ### 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

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

for (i in 0..args.lastIndex) { println(args[i]) }
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]) }
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]) }
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) }
91. ### 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) }
92. ### 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) }
93. ### 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) }
94. ### Iteration with indexes How can I get both the current

index and element?

\$arg") }
96. ### Iteration with indexes for ((index, arg) in args.withIndex()) { println("\$index:

\$arg") } args.forEachIndexed { index, arg -> println("\$index: \$arg") }
97. ### Iteration with indexes for ((index, arg) in args.withIndex()) { println("\$index:

\$arg") } args.forEachIndexed { index, arg -> println("\$index: \$arg") }
98. ### Iteration with indexes for ((index, arg) in args.withIndex()) { println("\$index:

\$arg") } args.forEachIndexed { index, arg -> println("\$index: \$arg") }

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

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

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

{ println("Clicked!") } })
105. ### SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

{ println("Clicked!") } }) button.setListener { println("Clicked!") }
106. ### SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

{ println("Clicked!") } }) button.setListener { println("Clicked!") }
107. ### SAM conversions button.setListener(object : OnClickListener { override fun onClick(button: Button?)

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

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

fun onClick(button: Button) { println("Clicked!") } }) }
110. ### SAM conversions #1 button.setListener { object : OnClickListener { override

fun onClick(button: Button) { println("Clicked!") } }) }
111. ### SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

Button?) { object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
112. ### SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

Button?) { val listener = object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
113. ### 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(...) } })
114. ### SAM conversions #1 button.setListener(object : OnClickListener { override fun onClick(button:

Button?) { object : OnClickListener { override fun onClick(button: Button) { println("Clicked!") } }) } })
115. ### SAM conversions #1 button.setListener { object : OnClickListener { override

fun onClick(button: Button) { println("Clicked!") } }) }
116. ### SAM conversions #1 button.setListener { object : OnClickListener { override

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

118. ### SAM conversions #2 • What if I need to reference

the listener instance? button.setListener { button.removeListener(this) }
119. ### SAM conversions #2 • What if I need to reference

the listener instance? button.setListener(object: OnClickListener { override fun onClick(button: Button) { button.removeListener(this) } }) button.setListener { button.removeListener(this) }

error?

}

}
123. ### SAM conversions #3 public interface OnClickListener { boolean onClick(Button button);

} button.setListener { println("Clicked!") }
124. ### SAM conversions #3 public interface OnClickListener { boolean onClick(Button button);

} button.setListener { println("Clicked!") } Kotlin: Type mismatch: inferred type is Unit but Boolean was expected
125. ### SAM conversions #3 public interface OnClickListener { boolean onClick(Button button);

} button.setListener { println("Clicked!") true }
126. ### SAM conversions #3 public interface OnClickListener { boolean onClick(Button button);

} button.setListener { println("Clicked!") true }

in Java?

129. ### SAM conversions #4 • SAM constructor button.setListener(OnClickListener { println("Clicked!") })

Java interface Kotlin interface Java method SAM conversion Object expression Kotlin method SAM constructor Object expression
130. ### Replacing statics #1 How do I create static functions and

variables in Kotlin?
131. ### Replacing statics class Foo { companion object { fun x()

{ ... } } fun y() { ... } }
132. ### Replacing statics class Foo { companion object { fun x()

{ ... } } fun y() { ... } } Foo.x()
133. ### Replacing statics class Foo { companion object { fun x()

{ ... } } fun y() { ... } } object Foo { fun x() { ... } } Foo.x() Foo.x()
134. ### Replacing statics class Foo { companion object { fun x()

{ ... } } fun y() { ... } } object Foo { fun x() { ... } } fun x() { ... } Foo.x() Foo.x() x()
135. ### Replacing statics class Foo { companion object { fun x()

{ ... } } fun y() { ... } } object Foo { fun x() { ... } } fun x() { ... } Foo.x() Foo.x() x()
136. ### 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
137. ### 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

139. ### Static initializers class X { companion object { init {

println("Static initialization!") } } }

working?
141. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { if (toy != null) { toy.chew() } } }
142. ### 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
143. ### Smart casts on mutable properties class Dog(val toy: Toy? =

null) { fun play() { if (toy != null) { toy.chew() } } }
144. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { if (toy != null) { toy.chew() } } }
145. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { val _toy = toy if (_toy != null) { _toy.chew() } } }
146. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { toy?.let { it.chew() } } }
147. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { toy?.chew() } }
148. ### Smart casts on mutable properties class Dog(var toy: Toy? =

null) { fun play() { toy?.let { it.chew() it.chew() it.chew() } } }

152. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() }
153. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date?
154. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } WeekDay Date?
155. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date WeekDay Date?
156. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date
157. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date date as Date
158. ### null!! class Episode { var airdate: Date = null!! }

fun getWeekDay(date: Date?): WeekDay { return date!!.getWeekDay() } Date date as Date throw NullPointerException()
159. ### null!! class Episode { var airdate: Date = null!! }

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

}

164. ### Platform types in overrides How do I choose the right

type when overriding Java methods?

button); }
167. ### 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}") } }
168. ### 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}") } }
169. ### 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}") } }
170. ### 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}") } }

names?

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

... } package com.example.square fun indent(str: String) : String { ... }
174. ### 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")
175. ### Import aliases package com.example.code fun String.indent() : String { ...

} package com.example.square fun String.indent() : String { ... }
176. ### 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()
177. ### 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()
178. ### Import aliases import java.util.Date as UtilDate import java.sql.Date as SqlDate

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