Learn more
Unit 1
Kotlin programs
Controlling program flow
Classes
Unit 2
Classes
Lists
Loops
Strings
Miscellaneous
Unit 3
Sets
Maps
Collection Operations
Scope functions
Miscellaneous
Unit 4
Coroutines
Miscellaneous
This Kotlin Quick Guide summarizes the topics covered in the Android Basics in Kotlin course in the form of code snippets.
- See the Kotlin Language Documentation for full reference.
- See the Kotlin Koans for more snippets to practice with. Note: This brings you to an external kotlinlang.org site that is developed by JetBrains.
The smallest main()
program for printing text
fun main() {
println("Hello, world!")
}
Printing a line of text
println("This is the text to print!")
Inline comments
// This is a comment line.
// This is another comment.
Variables
// Assign once, cannot change.
val age = "5"
val name = "Rover"
// Assign and change as needed.
var roll = 6
var rolledValue: Int = 4
Printing variables with string templates
println("You are already ${age}!")
println("You are already ${age} days old, ${name}!")
Data types
Int // Whole positive and negative numbers and zero
String // Piece of text between quotes
IntRange // Setting a range such as 1..6
Boolean // Can only be true or false
Function without arguments
// Define the function.
fun printHello () {
println ("Hello Kotlin")
}
// Call the function.
printHello()
Function with arguments
fun printBorder(border: String, timesToRepeat: Int) {
repeat(timesToRepeat) {
print(border)
}
println()
}
Function that returns a value
fun roll(): Int {
val randomNumber = (1..6).random()
return randomNumber
}
Basic operators
* // multiplication
/ // division
+ // addition
- // subtraction
= // assignment
Logic operators
> // greater than
< // less than
== // equal
>= // greater or equal
<= // less or equal
!= // not equal
Creating random numbers
val randomNumber = diceRange.random()
fun roll() {
val anotherRandomNumber = (1..6).random()
println(randomNumber)
}
Repeating an action with repeat()
fun printBorder() {
repeat(23) {
print("=")
}
}
Nesting repeat()
loops
fun printCakeBottom(age: Int, layers: Int) {
repeat(layers) {
repeat(age + 2) {
print("@")
}
println()
}
}
Conditional statements with if
/else
fun main() {
val num = 4
if (num > 4) {
println("The variable is greater than 4")
} else if (num == 4) {
println("The variable is equal to 4")
} else {
println("The variable is less than 4")
}
}
Conditional statements with when
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
4 -> println("No luck! You rolled a 4. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! you rolled a 6. Try again!")
}
Assigning the result of a when
statement to a variable
// Determine which drawable resource ID to use based on the dice roll.
val drawableResource = when (diceRoll) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
Simple class with property and method
class Dice {
var sides = 6
fun roll() {
val randomNumber = (1..6).random()
println(randomNumber)
}
}
Class with parameter
class Dice (val numSides: Int) {
fun roll(): Int {
val randomNumber = (1..numSides).random()
return randomNumber
}
}
Creating instances
val myFirstDice = Dice(6)
Abstract class
abstract class Dwelling() {
}
Abstract class with an abstract property
abstract class Dwelling() {
abstract val buildingMaterial: String
}
Abstract class with an abstract method
abstract class Dwelling() {
abstract fun floorArea(): Double
}
Mark a class open
so it can be subclassed
open class RoundHut(residents: Int) {
}
Create a subclass by extending a parent class
class SquareCabin : Dwelling()
Override a function from a superclass
override fun floorArea(): Double {
}
Call the superclass implementation of a function
override fun floorArea(): Double {
return super.floorArea() * floors
}
Define a read-only list
val numbers = listOf(1, 2, 3, 4, 5, 6)
Get the size of the list
numbers.size
Get the first item of a list
numbers[0]
Get a copy of a list in reverse order
listOf("red", "blue", "green").reversed()
Define a mutable list of strings
val entrees = mutableListOf<String>()
Add an item to a mutable list
entrees.add("spaghetti")
Modify an item in a mutable list
entrees[0] = "lasagna"
Remove an item from a mutable list
entrees.remove("lasagna")
Use for
loop to iterate over items in a list
for (element in myList) {
// Perform an operation with each item
println(element)
}
Use while
loop to iterate over items in a list
var index = 0
while (index < myList.size) {
println(myList[index])
index++
}
Number of characters in a String
val name = "Android"
println(name.length)
Use a variable in a String template
val number = 10
println("$number people")
Use an expression in a String template
val number = 10
val groups = 5
println("${number * groups} people")
Augmented assignments
a += b // a = a + b
a -= b // a = a - b
a *= b // a = a * b
a /= b // a = a / b
Use with
to simplify access to an object
with(squareCabin) {
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
}
Import from the Kotlin math library
import kotlin.math.PI
Use fully qualified name for a constant in the Kotlin math library (no import statement needed)
kotlin.math.PI * radius * radius
Chain calls together (for accessing properties and calling methods)
val stringInTextField = binding.costOfService.text.toString()
Variable number of function arguments
fun addToppings(vararg val toppings: String)
Package declaration
package com.example.affirmations.model
Create a set from a list
val numbers = listOf(0, 3, 8, 4, 0, 5, 5, 8, 9, 2)
val setOfNumbers = numbers.toSet()
Define a set
val set1 = setOf(1,2,3)
val set2 = mutableSetOf(3, 4, 5)
Set operations
set1.intersect(set2) // 3
set1.union(set2) // 1, 2, 3, 4, 5
Define a mutable map
val peopleAges = mutableMapOf<String, Int>(
"Fred" to 30,
"Ann" to 23
)
Set a value in a mutable map
peopleAges.put("Barbara", 42)
peopleAges["Joe"] = 51
Iterate over a collection
peopleAges.forEach { print("${it.key} is ${it.value}, ") }
// Fred is 31, Ann is 23, Barbara is 42, Joe is 51,
Transform each item in a collection
println(peopleAges.map { "${it.key} is ${it.value}" }.joinToString(", ") )
// Fred is 31, Ann is 23, Barbara is 42, Joe is 51
Filter the items in a collection
val filteredNames = peopleAges.filter { it.key.length < 4 }
println(filteredNames)
// {Ann=23, Joe=51}
Other collection operations
val words = listOf("about", "acute", "balloon", "best", "brief", "class")
val filteredWords = words.filter { it.startsWith("b", ignoreCase = true) }
.shuffled() // [brief, balloon, best]
.take(2) // [brief, balloon]
.sorted() // [balloon, brief]
let
arguments?.let {
letterId = it.getString(LETTER).toString()
}
apply
binding?.apply {
...
flavorFragment = this@FlavorFragment
}
Backing property
private var _currentScrambledWord = "test"
val currentScrambledWord: String
get() = _currentScrambledWord
Safe calls
val letterId = intent?.extras?.getString("letter").toString()
Lambda functions
val triple: (Int) -> Int = { a: Int -> a * 3 }
println(triple(5))
Companion objects
class DetailActivity: AppCompatActivity() {
...
companion object {
const val LETTER = "letter"
}
...
}
// accessible outside DetailActivity
DetailActivity.LETTER
Property delegation
// syntax
var <property-name> : <property-type> by <delegate-class>()
// example
private val viewModel: GameViewModel by viewModels()
Late initialization
private var wordsList: MutableList<String> = mutableListOf() // has a value at initialization
private lateinit var currentWord: String // needs to be assigned after initialization
Elvis operator
var quantity : Int? = null
quantity ?: 0 // 0
quantity = 4
quantity ?: 0 // 4
Declare a suspend function
suspend fun getValue(): Double {
// long running work or calls to other suspend functions
}
Run a suspend function in the GlobalScope
GlobalScope.launch {
val output = getValue()
}
Call suspend function from another suspend function.
suspend fun processValue() {
val value = getValue()
// modify the value
}
Access a coroutine Job
val job: Job = GlobalScope.launch {
val output = getValue()
}
Cancel a coroutine Job
job.cancel()
Run a suspend function and block the current thread until the function completes
runBlocking {
val output = getValue()
}
Use async to make a suspend function deferable
runBlocking {
val output = await { getValue() }
println("Output is ${output.await()}")
}
Declare an object
object DataProviderManager {
}
Catch an exception
try {
// code that may throw an error
} catch (exception: Exception) {
// handle the thrown exception
}
Create an enum class
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
Access an enum class value
val direction = Direction.NORTH
Check enum values
when (direction) {
Directon.NORTH -> {
}
Direction.SOUTH -> {
}
Direction.WEST -> {
}
Direction.EAST -> {
}
}
Last updated 2021-05-06 UTC.