Conventions
● The same conventions like on Java
● Uppercase for types
● Lower camelCase for methods and properties
● Semicolons are optional
● Reverse notation for packages
○ A file could contain multiple classes
○ The folder names not have to match the package name
Slide 19
Slide 19 text
Development tools
● JDK
○ JVM 1.6+
● Kotlin Compiler
● Editor or IDE
○ IntelliJ IDEA, Android Studio, NetBeans, Eclipse
Slide 20
Slide 20 text
*.kt
*.java
Kotlin
compiler
Java
compiler
*.class *.jar
App
Kotlin is 100% interoperable with Java
Kotlin
runtime
Slide 21
Slide 21 text
Build tools
● Maven
● Gradle
● Kobalt
● Ant
● Command Line
Basic Types
Type Size
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8
Slide 24
Slide 24 text
val vs
var
● val is immutable (read-only) and
you can only assign a value to
them exactly one time.
● var is mutable and can be
reassigned.
// immediate assignment
val countOfEvenNumbers: Int = 10
// `Int` type is inferred
var sumOfNumbers = 0
// type required when no
initializer is provided
var countOfPrimeNumbers: Int
// deferred assignment
countOfPrimeNumbers = 3
countOfPrimeNumbers = 24
Slide 25
Slide 25 text
String interpolation
● Simple reference uses $
● Complex references uses ${}
● Raw Strings """
val firstWord = "Learn "
val secondWord = "Kotlin"
var bothWords = "$firstWord
$secondWord"
println("$bothWords has
${bothWords.length}")
println(""""$bothWords" has
${bothWords.length}""")
Slide 26
Slide 26 text
No content
Slide 27
Slide 27 text
Null safety
● In an effort to rid the world of NullPointerException, variable types in
Kotlin don't allow the assignment of null.
● In order to use a variable that can be null, declare it nullable by adding ? at
the end of its type.
Slide 28
Slide 28 text
But wait...
The only possible causes of NPE's may be:
● An explicit call to throw NullPointerException()
● Usage of the !! operator (not-null assertion operator)
● Some data inconsistency with regard to initialization
● Java interoperation
Slide 29
Slide 29 text
// check for null in conditions
val trainingName: String? = "Learn Kotlin in 45 minutes"
if (trainingName != null && trainingName.isNotEmpty()) {
print("String of length ${trainingName.length}")
} else {
print("Empty string")
}
Slide 30
Slide 30 text
val platform: String? = null
val language = "Kotlin"
println(platform?.length) // safe call
println(language.length) // unnecessary safe call
val lengthOfWord = platform!!.length // !! operator
val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
Slide 31
Slide 31 text
val platform: String? = null
val language = "Kotlin"
println(platform?.length) // safe call
println(language.length) // unnecessary safe call
val lengthOfWord = platform!!.length // !! operator
val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
Slide 32
Slide 32 text
val platform: String? = null
val language = "Kotlin"
println(platform?.length) // safe call
println(language.length) // unnecessary safe call
val lengthOfWord = platform!!.length // !! operator
val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
Slide 33
Slide 33 text
// Elvis operator
val name: String? = null
val lengthOfName = name?.length ?: -1
println(lengthOfName)
Slide 34
Slide 34 text
// Elvis operator
val name: String? = null
val lengthOfName = name?.length ?: -1
println(lengthOfName) // => -1
// named arguments
fun getFullName(firstName: String, lastName: String): String {
return "$firstName $lastName"
}
getFullName(lastName = "Miu", firstName = "Magda")
Slide 44
Slide 44 text
class Utility {
// infix functions = functions with a single parameter
infix fun String.onto(other: String) = Pair(this, other)
}
fun main(args: Array) {
val blueShoes = "blue".onto("shoes")
val yellowScarf = "yellow" onto "scarf"
println(blueShoes) // => (blue, shoes)
println(yellowScarf) // => (yellow, scarf)
}
Slide 45
Slide 45 text
// functions with varargs parameters
fun varargExample(vararg names: Int) {
println("Argument has ${names.size} elements")
}
varargExample() // => Argument has 0 elements
varargExample(1) // => Argument has 1 elements
varargExample(1, 2, 3) // => Argument has 3 elements
Slide 46
Slide 46 text
// high order function = fun with fun or fun returns a fun
fun add(a: Int, b: Int): Int {
return a + b
}
fun returnAddFunction(): ((Int, Int) -> Int) {
return ::add
}
Slide 47
Slide 47 text
Lambda
● A lambda expression or an anonymous function is a “function literal”, i.e. a
function that is not declared, but passed immediately as an expression
● A lambda expression is always surrounded by curly braces
● Its parameters (if any) are declared before -> (parameter types may be
omitted)
● The body goes after -> (when present)
Slide 48
Slide 48 text
val sum: (Int, Int) -> Int = { a, b -> a + b }
println(sum(3,4))
Slide 49
Slide 49 text
val sum: (Int, Int) -> Int = { a, b -> a + b }
println(sum(3,4)) // => 7
Slide 50
Slide 50 text
// returning from a lambda
val calculateGrade = { grade : Int ->
when(grade) {
in 0..40 -> "Fail"
!is Int -> "Just a grade"
in 41..70 -> "Pass"
in 71..100 -> "Distinction"
else -> false
}
}
println(calculateGrade(57))
Slide 51
Slide 51 text
// returning from a lambda
val calculateGrade = { grade : Int ->
when(grade) {
in 0..40 -> "Fail"
!is Int -> "Just a grade"
in 41..70 -> "Pass"
in 71..100 -> "Distinction"
else -> false
}
}
println(calculateGrade(57)) // => Pass
Slide 52
Slide 52 text
Extension functions
● An extension function is a member function of a class that is defined outside
the class.
● Extensions are resolved statically and can also be defined with the class type
that is nullable.
● If a class contains a companion object, then we can also define extension
functions and properties for the companion object.
Slide 53
Slide 53 text
fun String.removeFirstLastChar(): String =
this.substring(1, this.length - 1)
Receiver type
Receiver object
Slide 54
Slide 54 text
fun String.removeFirstLastChar(): String =
this.substring(1, this.length - 1)
println("Kotlin".removeFirstLastChar())
fun reportError(): Nothing {
throw RuntimeException()
}
fun displayHelloMessage(): Unit {
println("Hello from Kotlin! :)")
}
Slide 58
Slide 58 text
fun reportError(): Nothing {
throw RuntimeException()
}
fun displayHelloMessage(): Unit {
println("Hello from Kotlin! :)")
}
Slide 59
Slide 59 text
Basic Data
Types
Numbers
Characters
Booleans
Arrays
Strings
Any
Nothing
Unit
Slide 60
Slide 60 text
Class
● There are primary and secondary constructors. For secondary we should add
the keyword constructor
● The primary constructor cannot contain any code.
Slide 61
Slide 61 text
// primary constructor with fullName property (setter & getter)
class Person(val fullName: String) { /*...*/ }
Slide 62
Slide 62 text
class Person(val fullName: String) {
val age: Int
get() {
return 18
}
// secondary constructor
constructor(fullName: String, age: Int) : this(fullName) {}
}
// instance of the class
val john = Person("John", 24)
Slide 63
Slide 63 text
Inheritance
● Inheritance: use open keyword
for class
● Overriding methods and
properties: use the open modifier
open class Person {
open val name = "Tom"
open fun displaySkills() { }
}
// inheritance and override
class Student : Person() {
override val name = "Jerry"
override fun displaySkills(){ }
}
Slide 64
Slide 64 text
// "object" keyword can be used to create singleton objects.
object TheObject {
fun hello() = "hello"
override fun toString() = "Hello, it's me,
${TheObject::class.simpleName}"
}
fun useSingletonObject() {
println(TheObject.hello()) // => hello
val someRef: Any = TheObject
println(someRef) // => Hello, it's me, TheObject
}
Slide 65
Slide 65 text
Delegation
● Composition over Inheritance design pattern
● Native support for delegation (implicit delegation)
● Zero boilerplate code
Slide 66
Slide 66 text
interface PetAction {
fun eat()
}
interface PetColor {
val color: String
}
object YellowColor : PetColor {
override val color = "yellow"
}
Slide 67
Slide 67 text
class PrintingPetAction(val food: String) : PetAction {
override fun eat() {
println(food)
}
}
class Cat(petColor: PetColor = YellowColor) :
PetAction by PrintingPetAction("eats a lot of fish"),
PetColor by petColor
Slide 68
Slide 68 text
class PrintingPetAction(val food: String) : PetAction {
override fun eat() {
println(food)
}
}
class Cat(petColor: PetColor = YellowColor) :
PetAction by PrintingPetAction("eats a lot of fish"),
PetColor by petColor
Slide 69
Slide 69 text
fun delegate() {
val kittyCat = Cat()
println("Pet has color ${kittyCat.color}")
kittyCat.eat()
}
fun main(args: Array) {
delegate()
}
// => Pet has color yellow
// => eats a lot of fish
Slide 70
Slide 70 text
Data classes are a concise way to create
classes that just hold data.
Data classes
Function Price
Getters and Setters 0 Lei
equals() & hashCode() 0 Lei
toString() 0 Lei
componentN() 0 Lei
copy() 0 Lei
TOTAL FREE!
Slide 71
Slide 71 text
data class Character(val name: String, val age: Int)
fun main() {
val mickeyMouse = Character("Mickey Mouse", 82)
val mickeyMouseToday = mickeyMouse.copy(age = 83)
// destructuring declarations
val (name, age) = mickeyMouseToday
println("$name, $age years of age")
mickeyMouseToday.component1() // => name
mickeyMouseToday.component2() // => age
}
Slide 72
Slide 72 text
Companion object
● companion object: syntactically
it's similar to the static methods
in Java
class Person {
companion object {
fun callMe() = "Call"
}
}
// Person.callMe()
// immutable list and mutable list
val numbersList = listOf("one", "two", "three")
val mutableNumbersList = mutableListOf("one", "two", "three")
listOf(1, 5, 3).sum() // => 9
listOf("a", "b", "cc").sumBy { it.length } // => 4
List
Slide 77
Slide 77 text
// immutable set and mutable set
val colors = setOf("red", "blue", "yellow")
val mutableColors = mutableSetOf("red", "blue", "yellow")
val longerThan3 = colors.filter { it.length > 3 } // => [blue, yellow]
Set
Slide 78
Slide 78 text
// immutable map and mutable map
val desserts = hashMapOf("whipped cream" to "cake", "chocolate" to
"cookie")
println(desserts["chocolate"])
val inventory = mutableMapOf("pancake" to 1)
inventory.put("cake", 3)
inventory.remove("pancake")
Map
Slide 79
Slide 79 text
// Sequences represent lazily-evaluated collections.
val fooSequence = generateSequence(1, { it + 1 })
val x = fooSequence.take(10).toList()
println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Sequence
Slide 80
Slide 80 text
Collection vs Sequence
Source: Collections and sequences in Kotlin by
Florina Muntenescu
Main advantages of Kotlin
● Readability
○ A code is clean if it is easy to understand
● Interoperability
○ Q: “Can I use my existing libraries?”
○ A: “Yes, absolutely!”
● Safety
○ Prevents some specific type of errors (NPE)
● Tooling
○ Kotlin is a compiled language (IntelliJ IDEA, Android Studio, NetBeans, Eclipse)
Slide 88
Slide 88 text
Best practices
1. Agree on conventions beforehand
2. Don’t treat it as Java with a different syntax
3. Use a linter (like ktlint)
4. Embrace the immutability
5. Reconsider if you need to use !! operator
6. Don’t hide too much info
7. Choose readable over short expressions
Slide 89
Slide 89 text
Kotlin is about developer happiness
and productivity.
Slide 90
Slide 90 text
Learn more...
Slide 91
Slide 91 text
No content
Slide 92
Slide 92 text
No content
Slide 93
Slide 93 text
No content
Slide 94
Slide 94 text
No content
Slide 95
Slide 95 text
Thank you!
Magda Miu @magdamiu
Squad Lead Developer at Orange
Android Google Developer Expert