Marton Braun
May 17, 2018
290

# 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]

2. Why do this talk?

3. Why do this talk?

4. Array vs
IntArray
What’s the difference? When do I use which one?

5. Array vs IntArray

6. Array vs IntArray
Array

7. Array vs IntArray
Array Integer[]

8. Array vs IntArray
Array Integer[]
val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

9. Array vs IntArray
Array Integer[]
IntArray
val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

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

11. Array vs IntArray
Array Integer[]
IntArray int[]
val intArray: IntArray = intArrayOf(1, 2, 3, 4, 5)
val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

12. Array vs IntArray

13. Array vs IntArray
• IntArray

14. Array vs IntArray
• IntArray
 Avoids boxing

15. Array vs IntArray
• IntArray
 Avoids boxing
 Easier to initialize
val intArray = IntArray(10)
val arrayOfInts = Array(5) { i -> i * 2 }

16. Array vs IntArray
• IntArray
 Avoids boxing
 Easier to initialize
• Array
val intArray = IntArray(10)
val arrayOfInts = Array(5) { i -> i * 2 }

17. Array vs IntArray
• IntArray
 Avoids boxing
 Easier to initialize
• Array
 Might be required by an API
val intArray = IntArray(10)
val arrayOfInts = Array(5) { i -> i * 2 }

18. Array vs IntArray
• IntArray
 Avoids boxing
 Easier to initialize
• Array
 Might be required by an API
 Can store nullable values
val intArray = IntArray(10)
val arrayOfInts = Array(5) { i -> i * 2 }
val notPeople: Array = arrayOfNulls(13)

19. Iterable vs
Sequence
What’s the difference? When do I use which one?

20. Iterable vs Sequence

21. Iterable vs Sequence
Iterable

22. Iterable vs Sequence
Iterable java.lang.Iterable

23. Iterable vs Sequence
 Eager evaluation
Iterable java.lang.Iterable

24. Iterable vs Sequence
 Eager evaluation
Iterable java.lang.Iterable
val people: List = getPeople()
val allowedEntrance = people
.filter { it.age >= 21 }
.map { it.name }
.take(5)

25. Iterable vs Sequence

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

46. Iterable vs Sequence

47. Iterable vs Sequence
Sequence

48. Iterable vs Sequence
Sequence
 Lazy evaluation

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

51. Iterable vs Sequence

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

72. Iterable vs Sequence
Sequence
 Lazy evaluation

73. Iterable vs Sequence
Sequence
 Lazy evaluation
 Potentially infinite

74. Iterable vs Sequence
Sequence
 Lazy evaluation
 Potentially infinite
generateSequence(1) { n -> n * 2 }
.take(20)
.forEach(::println)

75. Iterable vs Sequence

76. Iterable vs Sequence
• Iterable

77. Iterable vs Sequence
• Iterable
 Use by default

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

84. Iteration
How can / should I iterate over collections?

85. Iteration

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

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?

95. Iteration with indexes
for ((index, arg) in args.withIndex()) {
println("\$index: \$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")
}

99. SAM conversions
What are SAM conversions?

100. SAM conversions

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

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

103. SAM conversions

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!")
}

108. SAM conversions #1
Why are my listeners not being called?

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!")
}
}

117. SAM conversions #2
How do I reference my listener instance?

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

120. SAM conversions #3
Why am I getting a return type error?

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

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

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
}

127. SAM conversions #4
What if my interface/method is not written in Java?

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

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

138. Replacing statics #2

139. Static initializers
class X {
companion object {
init {
println("Static initialization!")
}
}
}

140. Smart casts on
mutable properties
Why are smart casts not 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()
}
}
}

149. null!!
Why am I getting NullPointerExceptions?

150. null!!

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

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

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

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

162. null!!
class Episode {
var airdate: Date = throw KotlinNullPointerException()
}

163. null!!
class Episode {
lateinit var airdate: Date
}

164. Platform types in
overrides
How do I choose the right type when overriding Java methods?

165. Platform types in overrides

166. Platform types in overrides
public interface OnClickListener {
void onClick(Button 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}")
}
}

171. Import aliases
What can I do about imports with conflicting names?

172. Import aliases

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 {
...
}

179. Kotlin vs Java for
Android development

180. Kotlin vs Java for Android development

181. Kotlin vs Java for Android development

182. Recap
• 1. Array vs IntArray
• 2. Iterable vs Sequence
• 3. Iteration (with indexes)
• 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

183. 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

184. Photo:
Alexey Sergeev
Questions?
zsmb.co zsmb13
[email protected]