This is a practical guide on kotlin language. This one file can be used as your pocket reference if you had already mastered the language or a life savior for the newbies who are looking for a short and simple tutorial.
I will try to update it frequently, but you can feel free to add examples in codes/
directory or commit changes in readme file
NOTE: This is exported from jupyter notebook. If you want that, mail me tbhaxor@gmail.com
Kotlin is a cross-platform, statically typed, general-purpose programming language with type inference
Every kotlin program starts from the main function, as demonstrated below
fun main(args: Array<String>) {
// your code
}
NOTE : Since this is an interactive notebook, the main
function part will be skipped.
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/println.html#println
println("Hello World")
Hello World
Variables are used to store the value of specific type, the types supported by kotlin there in documentation
Documentation: https://kotlinlang.org/docs/reference/basic-types.html, https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/
var age: Int = 22
age
22
Changing value of the variable
age = 30
age
30
Kotlin support three types of variables
var
→ mutable variables, values of such variables can be changed during the program setval
→ immutable variables, values of such variables can be initialized only single time
val i = 10
i
10
i = 20
Val cannot be reassigned
i
10
Using underscored number literal
val oneMillion = 1_000_000
oneMillion
1000000
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-float/
// the f means to use floating number, otherwise it will use the double and then type cast it into float
val price: Float = 44.77f;
price
44.77
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/
var name: String = "Gurkirat Singh"
name
Gurkirat Singh
Length of string
name.length
14
Getting one character
name[0] == name.get(0)
true
Comparing two strings
val name2 = "Gurkirat Singh"
name2
Gurkirat Singh
name == name2
true
name.compareTo(name2)
0
Here 0
means both strings are identical
Concatenating two strings
name.plus(name2)
Gurkirat SinghGurkirat Singh
name + name2
Gurkirat SinghGurkirat Singh
Collection of similar type of data
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/
var numbers = arrayOf(1, 2, 3, 4, 5, 6)
numbers
[Ljava.lang.Integer;@728561a2
To get the value, use the index number
numbers[0]
1
numbers[4]
5
Getting the length of array
numbers.size
6
Empty array of specific type
val emptyArray = arrayOf<Int>()
emptyArray
[Ljava.lang.Integer;@303524fb
emptyArray.size
0
val num1 = 1
val num2 = "2"
Both look identical (numbers), but the type of both the variables are not same
num1 + num2
None of the following functions can be called with the arguments supplied:
public final operator fun plus(other: Byte): Int defined in kotlin.Int
public final operator fun plus(other: Double): Double defined in kotlin.Int
public final operator fun plus(other: Float): Float defined in kotlin.Int
public final operator fun plus(other: Int): Int defined in kotlin.Int
public final operator fun plus(other: Long): Long defined in kotlin.Int
public final operator fun plus(other: Short): Int defined in kotlin.Int
num1 + num2.toInt()
3
Documentation: https://kotlinlang.org/docs/reference/keyword-reference.html#operators-and-special-symbols
val num1 = 20
val num2 = 30
Addition
num1 + num2
50
Subtraction
num2 - num1
10
Multiplication
num1 * num2
600
Division
num2 / num1
1
num2.toFloat() / num1.toFloat()
1.5
Finding remainder
num2 % num1
10
val num1 = 20
val num2 = 30
Equality
num1 == num2
false
NOTE: Don't misunderstand ==
with =
. First one is called equal to operator and another is called assignment operator (evaluates and assigns the RHS value to LHS)
Less than
num1 < num2
true
num2 < num2
false
Greater than
num1 > num2
false
Greater than equal to
num1 >= num1
true
Less than equal to
num1 <= num1
true
Not equal to
num1 != num2
true
var num1 = 10
num1
10
Post increment
num1++
num1
11
Pre increment
++num1
num1
12
Post decrement
num1--
num1
11
Pre decrement
--num1
num1
10
var num1 = 10
var num2 = 20
num1.toString(2)
1010
num2.toString(2)
10100
Shift left by one bit
num1 = num1.shl(1)
num1.toString(2)
10100
Shift right by one bit
num1 = num1.shr(1)
num1.toString(2)
1010
Bitwise or
num1.or(num2).toString(2)
11110
Bitwise and
num1.and(num2).toString(2)
0
Bitwise xor
num1.xor(num2).toString(2)
11110
num1.and(num1).toString(2)
1010
Bitwise inverse
num1.inv().toString(2)
-1011
num1.inv()
-11
AND operator
true && true
true
false && true
false
true && false
false
false && false
false
OR operator
true || true
true
true || false
true
false || true
true
false || false
false
NOT Operator
true && !false
true
Documentation: https://kotlinlang.org/docs/reference/control-flow.html#if-expression
var age = 18
var age2 = 14
if (age >= 18) {
println("You are an adult")
}
else {
println("Hey kiddo")
}
You are an adult
if (age2 >= 18) {
println("You are an adult")
}
else {
println("Hey kiddo")
}
Hey kiddo
Documentation: https://kotlinlang.org/docs/reference/control-flow.html#when-expression
var num = 4
when(num) {
1 -> println("Sunday")
2 -> println("Monday")
3 -> println("Tuesday")
4 -> println("Wednesday")
5 -> println("Thursday")
6 -> println("Friday")
7 -> println("Saturday")
else -> println("Number should be in between 1 and 7") // will be executed if no value matches
}
Wednesday
To run same lines of code for multiple choices
when(variable) {
1, 2, 3 -> println("your input is either 1 or 2 or 2")
else -> {
// running multiple lines
println("This is not a joke")
println("Enter number 1, 2, 3 only")
}
}
To run same lines of code for a range of numbers
when(variable) {
in 1..3 -> println("your input is either 1 or 2 or 2")
else -> {
// running multiple lines
println("This is not a joke")
println("Enter number 1, 2, 3 only")
}
}
Documentation: https://kotlinlang.org/docs/reference/control-flow.html#for-loops
var numbers = arrayOf<Int>(1, 2, 3, 4, 5, 6)
Simple demonstration
for (number in numbers){
println(number)
}
1
2
3
4
5
6
With indices
for ((idx, number) in numbers.withIndex()) {
println("number '$number' is at index '$idx' in the array")
}
number '1' is at index '0' in the array
number '2' is at index '1' in the array
number '3' is at index '2' in the array
number '4' is at index '3' in the array
number '5' is at index '4' in the array
number '6' is at index '5' in the array
Range based loop
for (i in 1..5)
{
println(i)
}
1
2
3
4
5
Range based loop with step
for (i in 1..5 step 2)
{
println(i)
}
1
3
5
Reverse loop with step
for (i in 6 downTo 0 step 2)
{
println(i)
}
6
4
2
0
Documentation: https://kotlinlang.org/docs/reference/control-flow.html#while-loops
var num = 5
while (num > 0)
{
println(num--)
}
5
4
3
2
1
do {
println(num--)
} while (num > 0)
0
Difference between while and do-while loop: https://stackoverflow.com/a/3347010/10362396
Jump statements like break
and continue
are used to end and skip the following loop body.
Documentation: https://kotlinlang.org/docs/reference/returns.html#returns-and-jumps
A function is a unit of code that performs a special task. In programming, function is used to break the code into smaller modules which makes the program more manageable.
Documentation: https://kotlinlang.org/docs/reference/functions.html#function-declarations
fun greet() {
println("Hello User")
}
greet()
Hello User
fun sum(x: Int, y: Int) {
println(x+y)
}
sum(10, 11)
21
Calling function with wrong type
sum(10.4f, 11)
The floating-point literal does not conform to the expected type Int
fun say_hello(name: String) : String {
return "Hello, " + name
}
say_hello("John")
Hello, John
say_hello("Dale")
Hello, Dale
A function which calls itself is called as recursive function and this process of repetition is called recursion.
fun factorial(num: Int): Int {
// base condition
if (num <= 1) {
return 1
}
// function calling itself
return num * factorial(num - 1)
}
factorial(5)
120
Documentation: https://kotlinlang.org/docs/reference/functions.html#default-arguments
fun say_hello_default(name: String = "Guest"): String {
return "Hello, " + name
}
say_hello_default()
Hello, Guest
say_hello_default("Sheldon")
Hello, Sheldon
Documentation: https://kotlinlang.org/docs/reference/functions.html#named-arguments
fun say_hello_default_name(name: String = "Guest", robot: String): String {
return "Hello, " + name + ". I am " + robot
}
say_hello_default_name(robot = "Alex")
Hello, Guest. I am Alex
say_hello_default_name("Dale", robot = "Alice")
Hello, Dale. I am Alice
The lambda functions are the functions that are not declared, but passed immediately as an expression
Documentation: https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions
fun multiply(x: Int, y: Int, callback: (Int) -> Unit)
{
callback(x * y)
}
var cb: (Int) -> Unit = {p -> println("The product is $p") } // lambda function
multiply(10, 20, cb)
The product is 200
Function that accept functions as the parameters and can return function as a value. This is basically implemented by the lambda functions
Documentation: https://kotlinlang.org/docs/reference/lambdas.html#higher-order-functions
var fn:(Int, Int) -> Int = {x, y-> x + y};
fun adder(num1: Int, num2: Int, callback: (Int, Int) -> Int): Int {
return callback(num1, num2)
}
adder(10, 20, fn)
30
Documentation: https://kotlinlang.org/docs/reference/inline-functions.html
inline fun inlineFunc(myFunc: () -> Unit): Unit {
myFunc()
}
inlineFunc({println("Printing inside inline function")})
Printing inside inline function
Documentation: https://kotlinlang.org/docs/tutorials/kotlin-for-py/exceptions.html#throwing-and-catching
var num1 = 100
var num2 = 0
try {
num1 / num2
} catch (e: ArithmeticException) {
println("Attempeted divide by zero")
}
Attempeted divide by zero
fun toInt(v: String): Int {
return try {
Integer.parseInt(v)
} catch (e: NumberFormatException) {
0
}
}
toInt("10")
10
toInt("hello")
0
The finally blocks runs regardless of the successful or failed execution
try {
// some code
} catch (e: Exception) {
//some execption
} finally {
// this will run after try or catch block execution
}
fun divMe(x: Int, y: Int): Int {
if (y < 0){
throw IllegalArgumentException("y should be strictly greater than 0")
}
return x / y
}
try {
divMe(10, 0)
} catch (e: ArithmeticException) {
print("Aborted: ")
println(e)
} catch (e: IllegalArgumentException) {
print("Aborted: ")
println(e)
}
Aborted: java.lang.ArithmeticException: / by zero
try {
divMe(10, -20)
} catch (e: ArithmeticException) {
print("Aborted: ")
println(e)
} catch (e: IllegalArgumentException) {
print("Aborted: ")
println(e)
}
Aborted: java.lang.IllegalArgumentException: y should be strictly greater than 0
Documentation: https://kotlinlang.org/docs/reference/null-safety.html#nullable-types-and-non-null-types
var myVar: Int = 7
myVar
7
myVar = 10
myVar
10
myVar = null
Null can not be a value of a non-null type Int
Use Int?
while defining the variable, so as to accept null values
var myVar: Int? = 7
myVar
7
myVar = 10
myVar
10
myVar = null
myVar
Documentation: https://kotlinlang.org/docs/reference/null-safety.html#safe-casts
var num: Int? = 19
num = null
var num2: Int? = num as? Int
num2
num = 10
var num2: Int? = num as? Int
num2
10
Documentation: https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator
val s1: String? = null;
val s2: String? = "Hello World";
var l1: Int = if (s1 != null) s1.length else -1
l1
-1
var l2: Int = if (s2 != null) s2.length else -1
l2
11
Simplifying the above with elvis operator
var l1: Int = s1 ?.length ?: -1
l1
-1
var l2: Int = s2 ?.length ?: -1
l2
11
Documentation:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html
var numbers = listOf(1, 2, "3", 4, 5)
for (number: Any in numbers) {
println(number)
}
1
2
3
4
5
List with type specification
var numbers = listOf<Int>(1, 2, 3, 4, 5)
for (number: Int in numbers) {
println(number)
}
1
2
3
4
5
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html
var list = mutableListOf<Int>()
list.isEmpty()
true
list.size
0
Adding an element
list.add(10)
list.size
1
list[0]
10
Adding multiple elements
list.addAll(listOf(20, 30, 40))
list.size
4
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/array-list-of.html
var array = arrayListOf<Int>(10, 20, 30)
for(element in array) {
println(element)
}
10
20
30
array.add(100)
for(element in array) {
println(element)
}
10
20
30
100
array[2] = -100
for(element in array) {
println(element)
}
10
20
-100
100
Inserting at specific location
array.add(1, -200)
for(element in array) {
println(element)
}
10
-200
20
-100
100
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-of.html
var map: Map<String, Int> = mapOf<String, Int>("ONE" to 1, "TWO" to 2)
map["ONE"]
1
map.keys
[ONE, TWO]
for (key in map.keys) {
println(map[key])
}
1
2
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-map-of.html
var map = mutableMapOf<Int, String>(10 to "TEN", 20 to "TWENTY")
map
{10=TEN, 20=TWENTY}
map[10]
TEN
map[30] = "THIRTY"
for(key in map.keys) {
println(map[key])
}
TEN
TWENTY
THIRTY
It is an implementation of the interface MutableMap
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-map/
var hmap: HashMap<Int, String> = HashMap<Int, String>();
// HashMap<Int, String>(initalCapacity) use this to reserve the memory while initilization
// you can add more keys later on
hmap.put(1, "Spiderman")
hmap.put(2, "Ironman")
hmap.put(3, "Black Widow")
hmap.put(4, "Ant Man")
hmap[1]
Spiderman
hmap.get(2)
Ironman
hmap.keys
[1, 2, 3, 4]
for(key in hmap.keys) {
println(hmap[key])
}
Spiderman
Ironman
Black Widow
Ant Man
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-map-of.html
var hmap = hashMapOf<Int, Int>(1 to 10, 2 to 20)
hmap.size
2
for(key in hmap.keys) {
println(hmap[key])
}
10
20
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/#kotlin.collections.Set
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/set-of.html
var set1 = setOf(1, 2, 3, 4, 4, 2, 3)
set1
[1, 2, 3, 4]
for(element in set1){
println(element)
}
1
2
3
4
set1.contains(1)
true
set1.contains(10)
false
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-set-of.html
val set2 = mutableSetOf<Int>()
set2.add(1)
set2.add(1)
set2.add(2)
set2.add(2)
set2.add(3)
true
set2
[1, 2, 3]
for(element in set2) {
println(element)
}
1
2
3
set2.remove(1)
true
set2.remove(5)
false
for(element in set2) {
println(element)
}
2
3
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-set-of.html
val set3 = hashSetOf<Int>(1, 2, 3, 5)
set3
[1, 2, 3, 5]
for(el in set3) {
println(el)
}
1
2
3
5
Documentation: https://kotlinlang.org/docs/tutorials/kotlin-for-py/classes.html#declaration-and-instantiation
class Vehicle {
// class properties
var speed: Int = 0
var wheels: Int = 0
var model: String = ""
// class methods
fun SetModel(m: String) {
model = m
}
fun SetSpeed(s: Int) {
speed = s
}
}
var vehicle1 = Vehicle()
vehicle1
Line_166_jupyter$Vehicle@6400abd0
vehicle1.model
vehicle1.SetModel("BMW")
vehicle1.model
BMW
vehicle1.wheels
0
vehicle1.wheels = 4
vehicle1.wheels
4
Documentation: https://kotlinlang.org/docs/reference/nested-classes.html#nested-and-inner-classes
class C1 {
fun ShowMe() {
println("From Outer Class C1")
}
class C2 {
fun ShowMe() {
println("From Inner Class C2")
}
}
}
var c1 = C1()
c1.ShowMe()
From Outer Class C1
var c2 = C1.C2()
c2.ShowMe()
From Inner Class C2
Documentation: https://kotlinlang.org/docs/reference/classes.html#constructors
class Car {
var wheels: Int
var model: String
init {
println("Starting the car")
wheels = 4
model = "BMW"
}
fun Stop() {
println("Stopping the car")
}
}
var car = Car()
Starting the car
car.wheels
4
car.Stop()
Stopping the car
class Vehicle(_wheels: Int, _model: String) {
var wheels: Int
var model: String
init {
println("starting")
wheels = _wheels
model = _model
}
fun Stop() {
println("stopping")
}
}
var v1 = Vehicle(4, "BMW")
var v2 = Vehicle(2, "Kawasaki Ninka")
starting
starting
v1.wheels
4
v2.wheels
2
v1.Stop()
v2.Stop()
stopping
stopping
NOTE: Keyword init
can be used multiple times
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name"
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}"
init {
println("Second initializer block that prints ${name.length}")
}
}
InitOrderDemo("hello")
First initializer block that prints hello
Second initializer block that prints 5
Line_186_jupyter$InitOrderDemo@7435796a
Documentation: https://kotlinlang.org/docs/reference/classes.html#secondary-constructors
class Person {
var name: String;
var age: Int;
constructor(name: String, age: Int) {
this.name = name;
this.age = age;
}
fun whoami() {
println("I am $name and I am $age years old.")
}
}
var p1 = Person("John", 23)
var p2 = Person("Sarrah", 44)
p1.whoami()
I am John and I am 23 years old.
p2.whoami()
I am Sarrah and I am 44 years old.
Documentation: https://kotlinlang.org/docs/reference/visibility-modifiers.html#classes-and-interfaces
class Person {
private var name: String;
constructor(name: String) {
this.name = name
}
fun whoami(): String {
return "I am $name"
}
}
var p1 = Person("Joel")
p1.whoami()
I am Joel
p1.name
Cannot access 'name': it is private in 'Person'
Documentation: https://kotlinlang.org/docs/reference/classes.html#inheritance
open class Vehicle {
public var wheels: Int = 0;
public var model: String = "";
fun Start() {
println("Starting")
}
fun Stop() {
println("Stop")
}
}
class Car: Vehicle {
constructor(model: String, wheels: Int) {
this.wheels = wheels
this.model = model
}
}
var car = Car("BMW", 4)
car.Start()
Starting
car.model
BMW
car.Stop()
Stop
Documentation: https://kotlinlang.org/docs/reference/classes.html#overriding-methods
open class Vehicle {
public var wheels: Int
constructor(wheels: Int) {
this.wheels = wheels
}
open fun Start() {
println("Starting the vehicle")
}
open fun Stop() {
println("Stopping the vehicle")
}
}
class Car(_wheels: Int): Vehicle(_wheels) {
init {
this.wheels = _wheels;
}
override fun Start() {
println("Starting the car")
}
override fun Stop() {
println("Stopping the car")
}
}
var car = Car(4)
car.wheels
4
car.Start()
Starting the car
car.Stop()
Stopping the car
Documentation: https://kotlinlang.org/docs/reference/classes.html#overriding-properties
open class Shape {
open protected val ndims: Int = 0
fun getDims(): Int {
return this.ndims
}
}
class Rectangle : Shape() {
override protected val ndims = 4
}
var rect = Rectangle()
rect.getDims()
4
rect.ndims
Cannot access 'ndims': it is protected in 'Rectangle'
Documentation: https://kotlinlang.org/docs/reference/classes.html#abstract-classes
abstract class Shape(_n: Int) {
protected var ndims: Int
init {
this.ndims = _n
}
public fun getDims(): Int {
return this.ndims
}
}
class Rect: Shape(4) {
}
var rect = Rect()
rect.getDims()
4
open class Person {
open fun sayHello() {
println("Hello from super class")
}
}
class Student: Person {
constructor() : super() {}
override fun sayHello() {
println("Hello from sub class")
super.sayHello()
}
}
var student = Student()
student.sayHello()
Hello from sub class
Hello from super class
Documentation: https://kotlinlang.org/docs/reference/data-classes.html#data-classes
data class Student(var name: String, var age: Int);
var student: Student = Student("John", 22)
student
Student(name=John, age=22)
student.name
John
student.age
22
Documentation: https://kotlinlang.org/docs/reference/whatsnew11.html#sealed-and-data-classes
sealed class Shape {
data class Circle (var radius: Int)
data class Rectangle (var width: Int, var height: Int)
data class Square (var side: Int)
}
var c = Shape.Circle(20)
c
Circle(radius=20)
var r = Shape.Rectangle(20, 10)
r
Rectangle(width=20, height=10)
var s = Shape.Square(20)
s
Square(side=20)
Documentation: https://kotlinlang.org/docs/reference/extensions.html#extension-functions
class Person {}
fun Person.sayHello(): String {
return "Hello"
}
var p = Person()
p.sayHello()
Hello
Documentation: https://kotlinlang.org/docs/reference/functions.html#generic-functions
fun <T> Return(x: T): T {
return x
}
Return<Int>(5)
5
Return<String>("Hello")
Hello
Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/
var str = "Hello world at 10:22!!"
var pattern = Regex("[0-9]{2}:[0-9]{2}")
pattern
[0-9]{2}:[0-9]{2}
pattern.containsMatchIn(str)
true
pattern.findAll(str)
kotlin.sequences.GeneratorSequence@53db2a04
Documentation: https://kotlinlang.org/docs/reference/java-interop.html
System.out.println("Hello")
Hello
Like Java, it also supports imports
Documentation: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html
filename: main.kt
fun main() {
}
fun Print() {
println("Calling from kotlin file")
}
filename: app.java
public class app
{
public static void main() {
MainKt.Print()
}
}