You are on page 1of 31

STARTING WITH KOTLIN

Starting with Kotlin


TABLE OF CONTENTS

Preface 2
Introduction 2
Key Features of Kotlin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Getting Started with Kotlin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Variables and Data Types 3
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Type Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Type Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Booleans. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Control Flow 12
If-Else Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
When Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
For Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
While Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Jump Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Functions 15
Function Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Default Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Named Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Variable Number of Arguments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Extension Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Higher-Order Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Tail Recursive Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Classes and Objects 19
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Data Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Object Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Companion Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Null Safety 22

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


1 STARTING WITH KOTLIN

Nullable and Non-Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22


Safe Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Elvis Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Non-Null Assertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Safe Casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Extensions and Lambdas 24
Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Extension Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Higher-Order Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Collections 26
Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Coroutines 28
Introduction to Coroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Launching Coroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Suspending Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Coroutine Context and Dispatchers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Async/Await . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Resources 30

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


2 STARTING WITH KOTLIN

PREFACE
PREFACE subclassing or modifying their implementation.

• Coroutines: Kotlin provides native support for


Welcome to the Kotlin Cheatsheet! This document
coroutines, which are lightweight concurrency
aims to provide you with a quick reference guide to
primitives that simplify asynchronous
Kotlin programming language. Whether you are a
programming and enable writing
beginner getting started with Kotlin or an
asynchronous code in a sequential manner.
experienced developer looking for a quick
reminder, this cheatsheet has got you covered. • Data Classes: Kotlin provides a concise syntax
for creating data classes that automatically
Kotlin is a modern, statically typed programming generate standard boilerplate code, such as
language developed by JetBrains. It is designed to equals(), hashCode(), toString(), and copy()
be concise, expressive, and interoperable with methods.
existing Java code. Kotlin is known for its safety
• Type Inference: Kotlin’s type inference system
features, null safety, and excellent support for
automatically infers the types of variables and
functional programming.
expressions, reducing the need for explicit type
declarations.
This cheatsheet is divided into several sections,
each focusing on a specific aspect of Kotlin • Smart Casts: Kotlin has smart casts that
programming. Each section provides code examples automatically cast variables after null checks,
and explanations to help you understand the eliminating the need for explicit type casts in
concepts better. Let’s dive in! many cases.

• Functional Programming: Kotlin supports


INTRODUCTION
INTRODUCTION functional programming constructs, such as
higher-order functions, lambda expressions,
Kotlin is a modern programming language that and immutability, making it suitable for
runs on the Java Virtual Machine (JVM) and can be functional programming paradigms.
used to develop various types of applications,
including Android apps, server-side applications,
GETTING STARTED WITH KOTLIN
and desktop applications. It was officially released
by JetBrains in 2016 and has gained popularity due
To start writing Kotlin code, you need to have the
to its concise syntax, null safety, and seamless
Kotlin compiler installed on your system. You can
interoperability with Java.
download the Kotlin compiler from the official
Kotlin website (https://kotlinlang.org) or use Kotlin
KEY FEATURES OF KOTLIN plugins for popular Integrated Development
Environments (IDEs) like IntelliJ IDEA, Android
• Concise Syntax: Kotlin provides a more Studio, or Eclipse.
concise and expressive syntax compared to
Java. It reduces boilerplate code and enhances Once you have the Kotlin compiler or plugin
readability. installed, you can create Kotlin source files with a
• Null Safety: Kotlin has built-in null safety .kt extension and start writing Kotlin code. Kotlin
features, which help eliminate null pointer code can be compiled and executed just like Java
exceptions by distinguishing nullable and non- code, as both Kotlin and Java bytecode run on the
nullable types at the language level. JVM.

• Interoperability: Kotlin is fully interoperable Here’s a simple "Hello, World!" program in Kotlin:
with Java, allowing developers to call Java code
from Kotlin and vice versa. This makes it easy
to adopt Kotlin gradually in existing Java fun main() {
projects. println("Hello, World!")
• Extension Functions: Kotlin allows you to }
extend existing classes with new functions,
even without modifying their source code. This
In this example, the main() function serves as the
enables adding new behavior to classes without

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


3 STARTING WITH KOTLIN

entry point of the program. The println() function Int


is used to print the string "Hello, World!" to the
console.
In this case, the Kotlin compiler infers the types of
You can compile and run the Kotlin code using the the variables based on the types of their initializers.
Kotlin compiler or your IDE’s built-in Kotlin
support. DATA TYPES

VARIABLESAND
ANDDATA
DATATYPES
TYPES Kotlin provides a rich set of data types, including
VARIABLES
both primitives and reference types. The following
table lists some commonly used data types in
Variables are used to store data in a program, and
Kotlin:
data types define the kind of data that can be stored
in a variable. Kotlin provides a rich set of data
types, including primitives and reference types. In Data Type Description
this section, we’ll explore variables, data types, type Byte 8-bit signed integer
inference, type aliases, strings, booleans, arrays,
Short 16-bit signed integer
ranges, and collections in Kotlin.
Int 32-bit signed integer
VARIABLES Long 64-bit signed integer

In Kotlin, variables are declared using the val or var Float 32-bit floating-point
keyword, followed by the variable name and an number
optional type annotation. The val keyword is used Double 64-bit floating-point
for read-only (immutable) variables, while the var number
keyword is used for mutable variables.
Char 16-bit Unicode character
Here’s an example of declaring variables in Kotlin: Boolean Represents the truth
values true and false

val message: String = "Hello, String Sequence of characters


Kotlin!" // Read-only variable Array Fixed-size ordered
var count: Int = 42 // Mutable collection of elements
variable
List Ordered collection of
elements
count = 10 // Variable can be
Set Unordered collection of
reassigned
unique elements
Map Collection of key-value
In this example, we declare a read-only variable
pairs
message of type String and initialize it with the
value "Hello, Kotlin!". We also declare a mutable
Here’s an example that demonstrates the use of
variable count of type Int and initialize it with the
different data types in Kotlin:
value 42. Later, we reassign the value of count to 10.

Kotlin supports type inference, so you can omit the


val age: Int = 25
type annotation if the type can be inferred from the
initializer expression:
val price: Double = 9.99
val name: String = "John Doe"
val isReady: Boolean = true
val message = "Hello, Kotlin!" //
Type inferred as String val numbers: Array<Int> = arrayOf(1,
var count = 42 // Type inferred as 2, 3, 4, 5)
val fruits: List<String> =

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


4 STARTING WITH KOTLIN

listOf("Apple", "Banana", "Orange") In this example, the return type of the add()
val uniqueNumbers: Set<Int> = function is inferred as Int because the expression a
+ b is of type Int. The result variable is also
setOf(1, 2, 3, 4, 5)
inferred as Int because it is assigned the value
val studentMap: Map<String, String>
returned by the add() function.
= mapOf("id" to "123", "name" to
"John Doe") Type inference improves code readability and
reduces redundancy, as you don’t have to explicitly
specify types that can be easily inferred.
In this example, we declare variables of different
data types and assign them with appropriate
values. The age variable is of type Int, the price TYPE ALIASES
variable is of type Double, the name variable is of
type String, and the isReady variable is of type Kotlin allows you to define type aliases, which
Boolean. We also declare variables of array, list, set, provide alternative names for existing types. Type
and map types and initialize them with sample aliases can be useful to make your code more
values. expressive or to provide descriptive names for
complex types.

TYPE INFERENCE To define a type alias, you use the typealias


keyword followed by the new name and the
Kotlin has a powerful type inference system that
existing type:
can automatically determine the types of variables
and expressions based on their context. This
eliminates the need for explicit type annotations in typealias Name = String
many cases and makes the code more concise.
typealias EmployeeData = Map<String,
When you initialize a variable with an expression,
Any>
the Kotlin compiler infers the type of the variable
based on the type of the expression: In this example, we define a type alias Name for the
String type and a type alias EmployeeData for the
Map<String, Any> type.
val name = "John Doe" // Type
inferred as String Type aliases can be used interchangeably with their
val count = 42 // Type inferred as corresponding types:
Int

val fullName: Name = "John Doe"


In this example, the Kotlin compiler infers that the val employee: EmployeeData =
name variable is of type String because it is
mapOf("name" to "John Doe", "age" to
initialized with a string literal. Similarly, it infers
30)
that the count variable is of type Int because it is
initialized with an integer literal.
In this example, we declare variables fullName and
Type inference also works with function return employee using the type aliases Name and
types and expressions: EmployeeData, respectively. Under the hood, these
variables have the same types as String and
Map<String, Any>, but the type aliases provide more
fun add(a: Int, b: Int) = a + b //
descriptive names.
Return type inferred as Int
Type aliases are particularly useful when you have
val result = add(2, 3) // Type complex types or generic types with long names.
inferred as Int They can make your code more readable and easier
to understand.

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


5 STARTING WITH KOTLIN

STRINGS
val a = 10
Strings are a fundamental data type in val b = 20
programming languages, and Kotlin provides rich val result = "The sum of $a and $b
support for working with strings. In Kotlin, strings
is ${a + b}"
are represented by the String class, which provides
various methods and operators for string
manipulation. In this example, the expression inside the curly
braces ${a + b} is evaluated and the result is
Creating Strings included in the result string template.

In Kotlin, you can create strings using string literals String templates make it easy to create dynamic
or by using the String constructor: strings without the need for string concatenation or
explicit conversion of variables to strings.

val message = "Hello, Kotlin!" // String Interpolation


String literal
val emptyString = String() // Empty String interpolation is a variant of string templates
string that allows you to specify a format for the
val charArray = charArrayOf('H', interpolated value. To perform string interpolation,
you use the syntax ${expression.format()}.
'e', 'l', 'l', 'o') // From char
array
Here’s an example that demonstrates string
interpolation:
In this example, we create a string message using a
string literal. We also create an empty string using
val pi = 3.14159
the String() constructor, and a string charArray by
converting a character array to a string. val formattedPi = "The value of pi
is %.2f".format(pi)
String Templates
In this example, we format the value of pi to two
String templates are a powerful feature in Kotlin
decimal places using the format() function with the
that allows you to embed expressions and variables
format specifier %.2f. The resulting string
inside string literals. To create a string template,
formattedPi is "The value of pi is 3.14".
you use the $ character followed by the expression
or variable name: String interpolation is particularly useful when you
need to control the formatting of interpolated
values, such as numbers or dates.
val name = "John Doe"
val greeting = "Hello, $name!"
String Operations and Functions
val count = 42
val message = "The count is $count" The String class in Kotlin provides various
operations and functions for string manipulation.
Here are some commonly used functions:
In this example, we use string templates to create
dynamic strings. The greeting string template
includes the value of the name variable, and the Function Description
message string template includes the value of the length() Returns the length of the
count variable. string.

You can also use curly braces {} for more complex isEmpty() Returns true if the string
expressions inside string templates: is empty.

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


6 STARTING WITH KOTLIN

Function Description string, convert it to uppercase, remove leading and


trailing whitespace using trim(), replace the word
isNotEmpty() Returns true if the string "Hello" with "Hi" using replace(), and split the
is not empty. string into substrings using split().
toUpperCase() Converts the string to
uppercase. The String class provides many more functions for
string manipulation, and you can refer to the Kotlin
toLowerCase() Converts the string to documentation for a complete list of available
lowercase. functions.
substring() Returns a substring of
the string. BOOLEANS
startsWith() Returns true if the string
Booleans are a fundamental data type that
starts with the specified
represents the truth values true and false. In
prefix.
Kotlin, the Boolean type is used to declare boolean
endsWith() Returns true if the string variables and express boolean logic.
ends with the specified
suffix. Here’s an example that demonstrates the use of
booleans in Kotlin:
contains() Returns true if the string
contains the specified
substring. val isTrue = true // Boolean
replace() Replaces occurrences of variable
a substring with another val isFalse = false // Boolean
substring. variable
trim() Removes leading and
trailing whitespace from val a = 10
the string. val b = 20
split() Splits the string into an
val isGreater = a > b // Boolean
array of substrings expression
based on a delimiter.
if (isGreater) {
Here’s an example that demonstrates some of these println("a is greater than b")
string functions: } else {
println("a is not greater than
b")
val message = " Hello, Kotlin! " }
println(message.length) // Output:
19
println(message.toUpperCase()) // In this example, we declare boolean variables
Output: " HELLO, KOTLIN! " isTrue and isFalse with the values true and false,
respectively. We also evaluate a boolean expression
println(message.trim()) // Output:
a > b and store the result in the isGreater variable.
"Hello, Kotlin!"
The if-else statement checks the value of isGreater
println(message.replace("Hello",
and prints the appropriate message.
"Hi")) // Output: " Hi, Kotlin!
" Boolean variables and expressions are commonly
println(message.split(",")) // used in conditional statements, loop conditions, and
Output: [" Hello", " Kotlin! "] logical operations.

In this example, we apply various string functions


to the message string. We calculate the length of the

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


7 STARTING WITH KOTLIN

ARRAYS In this example, we access the first element of the


numbers array using the index 0 and store it in the
Arrays are used to store fixed-size collections of
firstNumber variable. We also access the last
elements of the same type. In Kotlin, arrays are element of the array using the index numbers.size -
represented by the Array class, which provides 1 and store it in the lastNumber variable.
various operations for working with arrays.

Modifying Array Elements


Creating Arrays
You can modify individual elements of an array by
To create an array in Kotlin, you use the arrayOf() assigning a new value to them:
function and provide the elements of the array as
arguments:
val numbers = arrayOf(1, 2, 3, 4, 5)
numbers[2] = 10 // Modify the
val numbers = arrayOf(1, 2, 3, 4, 5) element at index 2
// Array of integers
val names = arrayOf("John", "Jane",
"Alice") // Array of strings In this example, we modify the element at index 2
of the numbers array and assign it the value 10.

In this example, we create an array numbers Array Functions


containing integers and an array names containing
strings. The Array class in Kotlin provides various functions
for working with arrays. Here are some commonly
You can also create an array with a specified size used functions:
and initialize it with default values using the
Array() constructor: Function Description
size Returns the size of the
val zeros = Array(5) { 0 } // Array array.
of size 5 initialized with zeros indices Returns the range of
val squares = Array(5) { it * it } valid indices for the
// Array of size 5 initialized with array.
squares get(index) Returns the element at
the specified index.
In this example, we create an array zeros of size 5 set(index, value) Sets the element at the
and initialize it with zeros. We also create an array specified index to the
squares of size 5 and initialize it with the squares of specified value.
the indices.
forEach { element → … Iterates over the
} elements of the array.
Accessing Array Elements
filter { element → … Returns a new array
You can access individual elements of an array } containing only the
using the indexing operator []: elements that satisfy the
specified condition.
map { element → … } Returns a new array
val numbers = arrayOf(1, 2, 3, 4, 5)
resulting from applying
val firstNumber = numbers[0] //
the specified
Access the first element
transformation to each
val lastNumber =
element.
numbers[numbers.size - 1] // Access
the last element

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


8 STARTING WITH KOTLIN

Function Description RANGES


plus(element) Returns a new array Ranges are a useful feature in Kotlin for
with the specified representing a sequence of values. Kotlin provides
element appended. the .. operator to create ranges and various
functions for working with ranges.
Here’s an example that demonstrates some of these
array functions: Creating Ranges

To create a range in Kotlin, you use the .. operator


val numbers = arrayOf(1, 2, 3, 4, 5) and specify the start and end values:
println(numbers.size) // Output: 5
println(numbers.indices) // Output:
0..4 val numbers = 1..5 // Range from 1
to 5 (inclusive)
numbers.forEach { println(it) } // val alphabets = 'a'..'z' // Range
Output: 1 2 3 4 5 from 'a' to 'z' (inclusive)

val filteredNumbers = numbers.filter In this example, we create a range numbers from 1 to


{ it % 2 == 0 } 5 (inclusive) and a range alphabets from 'a' to 'z'
println(filteredNumbers) // Output: (inclusive).
[2, 4]
You can also create a range that excludes the end
val squaredNumbers = numbers.map { value using the until function:

it * it }
println(squaredNumbers) // Output: val exclusiveRange = 1 until 5 //
[1, 4, 9, 16, 25] Range from 1 to 4 (exclusive)

val newArray = numbers.plus(6)


println(newArray) // Output: [1, 2, In this case, the range exclusiveRange includes
3, 4, 5, 6] values from 1 to 4 (exclusive of 5).

val removedArray = numbers.minus(3) Iterating over Ranges


println(removedArray) // Output: [1,
Ranges can be used to iterate over a sequence of
2, 4, 5] values using the for loop:

In this example, we apply various array functions


for (number in numbers) {
to the numbers array. We calculate the size of the
println(number)
array using size(), get the range of valid indices
using indices, iterate over the elements using
}
forEach, filter the even numbers using filter,
transform the numbers into their squares using map,
In this example, we use a for loop to iterate over
append an element using plus, and remove an the numbers range and print each value.
element using minus.

The Array class provides many more functions for Checking Value Membership
array manipulation, and you can refer to the Kotlin
You can check if a value is contained within a range
documentation for a complete list of available
using the in operator:
functions.

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


9 STARTING WITH KOTLIN

val number = 3 val numbers = 1..5


val isInRange = number in numbers // println(numbers.start) // Output: 1
Check if number is in the range println(numbers.endInclusive) //
Output: 5
In this example, we check if the number is contained
within the numbers range and store the result in the
println(3 in numbers) // Output:
isInRange variable. true
println(6 in numbers) // Output:
Range Functions
false

The IntRange and CharRange classes in Kotlin provide numbers.forEach { println(it) } //


various functions for working with ranges. Here Output: 1 2 3 4 5
are some commonly used functions:
println(numbers.count()) // Output:
Method Description 5
start Returns the start value println(numbers.sum()) // Output: 15
of the range. println(numbers.average()) //
endInclusive Returns the end value of Output: 3.0
the range. println(numbers.min()) // Output: 1
println(numbers.max()) // Output: 5
step Returns the step value of
the range.
val reversedNumbers =
contains(value) Returns true if the range numbers.reversed()
contains the specified println(reversedNumbers) // Output:
value.
5..1
isEmpty() Returns true if the range
is empty.
In this example, we apply various range functions
reversed() Returns a new range to the numbers range. We access the start and end
with the start and end values using start and endInclusive, check if values
values reversed. are in the range using contains, iterate over the
forEach { value → … } Iterates over the values values using forEach, calculate the count, sum,
in the range. average, minimum, and maximum using count, sum,
average, min, and max respectively. Finally, we create
count() Returns the number of a reversed range using reversed.
values in the range.

sum() Returns the sum of the The IntRange and CharRange classes provide many
values in the range. more functions for working with ranges, and you
can refer to the Kotlin documentation for a
average() Returns the average of complete list of available functions.
the values in the range.

min() Returns the minimum COLLECTIONS


value in the range.
Collections are used to store and manipulate groups
max() Returns the maximum
of elements in Kotlin. Kotlin provides a rich set of
value in the range.
collection classes and functions that make working
with collections easy and efficient.
Here’s an example that demonstrates some of these
range functions:

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


10 STARTING WITH KOTLIN

List Method Description

A list is an ordered collection of elements that add(index, element) Inserts the element at
allows duplicate elements. In Kotlin, the List the specified index.
interface represents an immutable (read-only) list, remove(element) Removes the first
while the MutableList interface represents a
occurrence of the
mutable (read-write) list.
element from the list.

To create a list in Kotlin, you can use the listOf() removeAt(index) Removes the element at
function: the specified index.
subList(fromIndex, Returns a new list
toIndex) containing the elements
val numbers = listOf(1, 2, 3, 4, 5)
between the indices.
// Immutable list
val names = mutableListOf("John",
Here’s an example that demonstrates some of these
"Jane", "Alice") // Mutable list list functions:

In this example, we create an immutable list


val numbers = listOf(1, 2, 3, 4, 5)
numbers and a mutable list names containing integers
and strings, respectively.
println(numbers.size) // Output: 5
println(numbers.isEmpty()) //
Lists provide various functions for accessing and Output: false
manipulating their elements:
println(numbers.get(2)) // Output: 3
Method Description println(numbers.contains(4)) //
size Returns the size of the Output: true
list.
val names = mutableListOf("John",
isEmpty Returns true if the list is
"Jane", "Alice")
empty.
names.add("Bob")
isNotEmpty Returns true if the list is names.remove("John")
not empty.
get(index) Returns the element at println(names) // Output: [Jane,
the specified index. Alice, Bob]
set(index, element) Sets the element at the
specified index to the In this example, we apply various list functions to
specified value. the numbers and names lists. We calculate the size of
contains(element) Returns true if the list the lists using size(), check if the lists are empty
contains the specified using isEmpty(), access elements using get(), check
element. if an element exists using contains(), add elements
using add(), and remove elements using remove().
indexOf(element) Returns the index of the
first occurrence of the
element. Set

lastIndexOf(element) Returns the index of the A set is an unordered collection of unique elements.
last occurrence of the In Kotlin, the Set interface represents an immutable
element. (read-only) set, while the MutableSet interface
add(element) represents a mutable (read-write) set.
Adds the element to the
end of the list.
To create a set in Kotlin, you can use the setOf()
function:

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


11 STARTING WITH KOTLIN

Output: false
val numbers = setOf(1, 2, 3, 4, 5)
// Immutable set println(numbers.contains(4)) //
val names = mutableSetOf("John", Output: true
"Jane", "Alice") // Mutable set
val names = mutableSetOf("John",
In this example, we create an immutable set numbers
"Jane", "Alice")
and a mutable set names containing integers and names.add("Bob")
strings, respectively. names.remove("John")

Sets provide various functions for accessing and println(names) // Output: [Jane,
manipulating their elements: Alice, Bob]

Function Description
In this example, we apply various set functions to
size Returns the size of the the numbers and names sets. We calculate the size of
set. the sets using size(), check if the sets are empty
isEmpty Returns true if the set is using isEmpty(), check if an element exists using
empty. contains(), add elements using add(), and remove
elements using remove().
isNotEmpty Returns true if the set is
not empty.
Map
contains(element) Returns true if the set
contains the specified A map is a collection of key-value pairs, where each
element. key is unique. In Kotlin, the Map interface represents
an immutable (read-only) map, while the
add(element) Adds the specified
MutableMap interface represents a mutable (read-
element to the set.
write) map.
remove(element) Removes the specified
element from the set. To create a map in Kotlin, you can use the mapOf()
function:
intersect(otherSet) Returns a new set
containing the common
elements between the val studentMap = mapOf("id" to 123,
set and the specified set.
"name" to "John Doe") // Immutable
union(otherSet) Returns a new set map
containing all elements val employee
from the set and the
specified set.
Map = mutableMapOf("id" to 456,
subtract(otherSet) Returns a new set "name" to "Jane Smith") // Mutable
containing the elements map
from the set excluding
the elements present in
the specified set. In this example, we create an immutable map
studentMap and a mutable map employeeMap
containing key-value pairs representing student
Here’s an example that demonstrates some of these
and employee data, respectively.
set functions:

Maps provide various functions for accessing and


val numbers = setOf(1, 2, 3, 4, 5) manipulating their elements:

println(numbers.size) // Output: 5
println(numbers.isEmpty()) //

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


12 STARTING WITH KOTLIN

Method Description val employeeMap = mutableMapOf("id"


to 456, "name" to "Jane Smith")
size Returns the number of
employeeMap.put("age", 30)
key-value pairs in the
employeeMap.remove("id")
map.
isEmpty Returns true if the map println(employeeMap) // Output:
is empty.
{name=Jane Smith, age=30}
isNotEmpty Returns true if the map
is not empty.
In this example, we apply various map functions to
containsKey(key) Returns true if the map the studentMap and employeeMap. We calculate the
contains the specified size of the maps using size(), check if the maps are
key. empty using isEmpty(), check if a key exists using
containsValue(value) Returns true if the map containsKey(), retrieve values using get(), add key-
contains the specified value pairs using put(), and remove key-value pairs
value. using remove().

get(key) Returns the value Collections in Kotlin provide a wide range of


associated with the functions and capabilities for working with data in
specified key, or null if a structured and efficient manner. They are a
the key is not found. fundamental part of many Kotlin programs, and
put(key, value) Associates the specified you can leverage their power to handle complex
value with the specified data scenarios.
key.
CONTROLFLOW
CONTROL FLOW
remove(key) Removes the key-value
pair with the specified
Control flow statements are used to control the
key.
execution flow of a program based on certain
keys Returns a set of all keys conditions or criteria. Kotlin provides a set of
in the map. control flow statements, including if-else
values expressions, when expressions, for loops, while
Returns a collection of
loops, and jump statements. In this section, we’ll
all values in the map.
explore each of these control flow statements in
entries Returns a set of all key- detail.
value pairs in the map.

IF-ELSE EXPRESSIONS
Here’s an example that demonstrates some of these
map functions: The if-else expression is used to conditionally
execute a block of code based on a boolean
condition. In Kotlin, the if-else expression can be
val studentMap = mapOf("id" to 123, used as an expression that returns a value.
"name" to "John Doe")
println(studentMap.size) // Output: Here’s the general syntax of the if-else expression:
2
println(studentMap.isEmpty()) //
val result = if (condition) {
Output: false
// Code to execute if the
condition is true
println(studentMap.containsKey("id")
} else {
) // Output: true
// Code to execute if the
println(studentMap.get("name")) //
condition is false
Output: "John Doe"
}

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


13 STARTING WITH KOTLIN

In this syntax, condition is the boolean expression }


that determines which block of code to execute. If branch2 -> {
the condition is true, the code inside the first block // Code to execute if value
is executed; otherwise, the code inside the second matches branch2
block is executed. }
branch3, branch4 -> {
The if-else expression returns a value that is
// Code to execute if value
assigned to the variable result. The type of the
value returned depends on the types of the code matches either branch3 or branch4
blocks. The types of the code blocks must be }
compatible, meaning they should either have the else -> {
same type or be subtypes of a common type. // Code to execute if value
doesn't match any branch
Here’s an example that demonstrates the use of if- }
else expressions:
}

val number = 10 In this syntax, value is the expression whose value


val result = if (number > 0) { is matched against the branches. Each branch
"Positive" consists of a value or a condition followed by the
} else if (number < 0) { code to execute if the value matches. If a branch’s
"Negative" value or condition matches the value, the
} else { corresponding code block is executed. If none of the
branches match the value, the code block inside the
"Zero"
else branch is executed.
}
The when expression returns a value that is
println(result) // Output: assigned to the variable result. The types of the
"Positive" values in the branches must be compatible,
meaning they should either have the same type or
be subtypes of a common type.
In this example, we use the if-else expression to
determine the sign of a number. If the number is
Here’s an example that demonstrates the use of
greater than 0, the first block is executed and the
when expressions:
string "Positive" is returned. If the number is less
than 0, the second block is executed and the string
"Negative" is returned. If the number is 0, the third val day = 3
block is executed and the string "Zero" is returned. val dayOfWeek = when (day) {
1 -> "Monday"
WHEN EXPRESSIONS 2 -> "Tuesday"
3 -> "Wednesday"
The when expression is used to conditionally
4 -> "Thursday"
execute code based on multiple branches. In Kotlin,
the when expression can be used as an expression
5 -> "Friday"
that returns a value or as a statement that performs else -> "Weekend"
an action. }

Here’s the general syntax of the when expression: println(dayOfWeek) // Output:


"Wednesday"
val result = when (value) {
branch1 -> { In this example, we use the when expression to
// Code to execute if value determine the day of the week based on the day
matches branch1 variable. If day is 1, the first branch matches and the

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


14 STARTING WITH KOTLIN

string "Monday" is returned. If day is 2, the second }


branch matches and the string "Tuesday" is
returned. If day is 3, the third branch matches and
In this example, we use a for loop to iterate over the
the string "Wednesday" is returned. If day is 4, the
range from 1 to 5 (inclusive) and print each value.
fourth branch matches and the string "Thursday" is
The loop assigns each value of the range to the
returned. If day is 5, the fifth branch matches and
variable i, and the code inside the loop prints the
the string "Friday" is returned. For any other value
value of i.
of day, the else branch matches and the string
"Weekend" is returned.
WHILE LOOPS
FOR LOOPS
The while loop is used to repeatedly execute a block
of code as long as a boolean condition is true. In
The for loop is used to iterate over a collection or a
Kotlin, the while loop is similar to while loops in
range of values. In Kotlin, the for loop is more
other programming languages.
concise and expressive compared to traditional for
loops found in other programming languages.
Here’s the general syntax of the while loop:

Here’s the general syntax of the for loop:

while (condition) {
for (element in collection) { // Code to execute while the
// Code to execute for each condition is true
element }
}
In this syntax, condition is the boolean expression
that determines whether to continue executing the
In this syntax, element is a variable that represents
code inside the loop. As long as the condition is
each element in the collection. The code inside the
true, the code inside the loop is executed
loop is executed once for each element in the
repeatedly.
collection.

Here’s an example that demonstrates the use of


Here’s an example that demonstrates the use of for
while loops:
loops:

val numbers = listOf(1, 2, 3, 4, 5) var count = 0

for (number in numbers) { while (count < 5) {


println(number) println(count)
} count++
}

In this example, we use a for loop to iterate over the


numbers list and print each element. The loop In this example, we use a while loop to repeatedly
assigns each element of the list to the number print the value of the count variable as long as it is
variable, and the code inside the loop prints the less than 5. The code inside the loop prints the value
value of number. of count and increments it by 1 in each iteration.

The for loop can also be used to iterate over a range JUMP STATEMENTS
of values:
Jump statements are used to transfer control to a
different part of the program. Kotlin provides three
for (i in 1..5) { jump statements: break, continue, and return.
println(i)

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


15 STARTING WITH KOTLIN

• The break statement is used to terminate the In this example, we use the break statement to
execution of a loop or a when expression. terminate the loop when the number is 3. When the
When the break statement is encountered, the break statement is encountered, the loop is
program execution resumes at the next terminated and the program execution resumes at
statement after the loop or the when the next statement after the loop. We also use the
expression. continue statement to skip the iteration when the
number is 2. When the continue statement is
• The continue statement is used to skip the
encountered, the program execution jumps to the
current iteration of a loop and move to the next
beginning of the loop and evaluates the loop
iteration. When the continue statement is
condition again.
encountered, the program execution jumps to
the beginning of the loop and evaluates the
In the sum function, we use the return statement to
loop condition again.
exit the function and return a value. If either a or b
• The return statement is used to exit a function is 0, the function exits immediately and returns 0.
or a lambda expression and return a value. Otherwise, it calculates the sum of a and b and
When the return statement is encountered, the returns the result.
program execution exits the current function
or lambda and returns the specified value, if Jump statements provide flexibility in controlling
any. the flow of a program, allowing you to terminate
loops early, skip iterations, or exit functions when
Here’s an example that demonstrates the use of certain conditions are met.
jump statements:
FUNCTIONS
FUNCTIONS
val numbers = listOf(1, 2, 3, 4, 5) Functions are a fundamental building block in
Kotlin that allow you to group and reuse code.
for (number in numbers) { Functions encapsulate a sequence of statements
if (number == 3) { and can accept input parameters and return output
break // Terminate the loop values. In this section, we’ll explore how to define
when number is 3 and use functions in Kotlin.
}
FUNCTION BASICS
if (number == 2) {
A function in Kotlin is declared using the fun
continue // Skip the
keyword, followed by the function name, a
iteration when number is 2
parameter list (optional), a return type (optional),
}
and a body enclosed in curly braces.

println(number) Here’s the general syntax of a function declaration:


}

fun sum(a: Int, b: Int): Int { fun functionName(parameters):


if (a == 0 || b == 0) { returnType {
return 0 // Exit the // Code to execute
function and return 0 if either a or // Optional return statement
b is 0 }
}
In this syntax:
return a + b
} • functionName is the name of the function.

• parameters is an optional comma-separated list


of input parameters, each with a name and a

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


16 STARTING WITH KOTLIN

type. In this example, the greet function has a parameter


name of type String with a default value of "Guest". If
• returnType is the optional return type of the
no argument is provided for name in a function call,
function.
the default value "Guest" is used.
• The body of the function contains the code to
be executed. Here are some examples of calling the greet
function:
Here’s an example of a simple function that
calculates the sum of two integers:
greet() // Output: "Hello, Guest!"
greet("John") // Output: "Hello,
fun sum(a: Int, b: Int): Int { John!"
return a + b
}
In the first example, we call the greet function
without providing an argument for name. Since no
In this example, we declare a function named sum argument is provided, the default value "Guest" is
that takes two parameters of type Int named a and used.
b. The function returns an Int value, which is the
sum of the parameters. In the second example, we call the greet function
and provide the argument "John" for name. The
Functions can be called by using their names provided argument overrides the default value, and
followed by parentheses containing the arguments. "John" is used instead.
Here’s an example that demonstrates calling the sum
function: Default arguments are useful when you want to
provide flexibility in function calls by allowing
some arguments to be omitted.
val result = sum(3, 4)
println(result) // Output: 7 NAMED ARGUMENTS

Kotlin allows you to specify function arguments by


In this example, we call the sum function with
name, instead of relying on the order of arguments.
arguments 3 and 4. The function calculates the sum
of the arguments and returns the result, which is
Here’s an example of a function with named
assigned to the result variable. Finally, we print the
arguments:
value of result, which outputs 7.

DEFAULT ARGUMENTS fun fullName(firstName: String,


lastName: String) {
Kotlin allows you to specify default values for println("Full Name: $firstName
function parameters. A default value is used when
$lastName")
no argument is provided for that parameter in a
}
function call.

Here’s an example of a function with default In this example, the fullName function has two
arguments: parameters: firstName and lastName. To specify the
arguments by name, you use the parameter names
followed by the = symbol.
fun greet(name: String = "Guest") {
println("Hello Here are some examples of calling the fullName
function using named arguments:
, $name!")
}
fullName(firstName = "John",

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


17 STARTING WITH KOTLIN

lastName = "Doe") // Output: "Full val result2 = sum(10, 20, 30)


Name: John Doe"
fullName(lastName = "Smith", In the first example, we call the sum function with
firstName = "Jane") // Output: "Full five arguments 1, 2, 3, 4, and 5. The function
Name: Jane Smith" calculates the sum of these numbers and returns
the result, which is assigned to the result1 variable.

In the first example, we call the fullName function


In the second example, we call the sum function
and specify the arguments by name. The order of
with three arguments 10, 20, and 30. The function
the arguments is not important because we
calculates the sum of these numbers and returns
explicitly provide the parameter names.
the result, which is assigned to the result2 variable.

In the second example, we provide the arguments


Varargs provide flexibility in function calls by
in a different order, but the function still produces
allowing a variable number of arguments to be
the correct output because we use the parameter
passed without explicitly creating an array or a
names to specify the arguments.
collection.

Named arguments are useful when a function has


many parameters and you want to make the EXTENSION FUNCTIONS
function calls more readable and self-explanatory.
Extension functions allow you to add new functions
to existing classes without modifying their source
VARIABLE NUMBER OF ARGUMENTS code. Extension functions are defined outside the
class they extend and can be called on instances of
Kotlin allows you to define functions with a
the extended class.
variable number of arguments, known as varargs.
Varargs are useful when you want to pass a
Here’s the general syntax of an extension function:
variable number of arguments of the same type to a
function.
fun
Here’s an example of a function with a vararg
ClassName.functionName(parameters):
parameter:
returnType {
// Code to execute
fun sum(vararg numbers: Int): Int { }
var total = 0
for (number in numbers) { In this syntax, ClassName is the name of the class
total += number being extended, functionName is the name of the
} extension function, parameters is the optional
return total comma-separated list of input parameters, and
} returnType is the return type of the function.

Here’s an example of an extension function that


In this example, the sum function takes a vararg calculates the square of an Int:
parameter numbers of type Int. The function
calculates the sum of all the numbers passed as
arguments and returns the result. fun Int.square(): Int {
return this * this
Here are some examples of calling the sum function }
with different numbers of arguments:

In this example, we define an extension function


val result1 = sum(1, 2, 3, 4, 5) square for the Int class. The extension function can
be called on instances of the Int class and calculates

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


18 STARTING WITH KOTLIN

the square of the value. a + b


}
Here’s an example of calling the square extension
function: val product = operateOnNumbers(5, 6)
{ a, b ->
val number = 5 a * b
val result = number.square() }
println(result) // Output: 25
In this example, we call the operateOnNumbers
function twice, passing different functions as the
In this example, we call the square extension
operation parameter. The first call calculates the
function on the number variable of type Int. The
sum of 3 and 4 using a lambda expression, and the
extension function calculates the square of the
second call calculates the product of 5 and 6 using
value 5 and returns the result, which is assigned to
another lambda expression.
the result variable. Finally, we print the value of
result, which outputs 25.
Higher-order functions enable you to write more
generic and reusable code by abstracting the
Extension functions are a powerful feature of
behavior of a function and allowing it to be
Kotlin that allows you to add functionality to
customized at runtime.
existing classes, even if you don’t have access to
their source code.
TAIL RECURSIVE FUNCTIONS
HIGHER-ORDER FUNCTIONS Kotlin supports tail recursion optimization, which
allows certain recursive functions to be executed
Higher-order functions are functions that can
without consuming additional stack space. A tail
accept other functions as parameters or return
recursive function is a function where the recursive
functions as results. Higher-order functions are a
call is the last operation in the function.
key feature of functional programming and enable
you to write code that is more concise and
To define a tail recursive function, you can use the
expressive.
tailrec modifier before the function declaration.

Here’s an example of a higher-order function that


Here’s an example of a tail recursive function that
takes a function as a parameter:
calculates the factorial of a number:

fun operateOnNumbers(a: Int, b: Int,


tailrec fun factorial(n: Int, acc:
operation: (Int, Int) -> Int): Int {
Int = 1): Int {
return operation(a, b)
return if (n == 0) {
}
acc
} else {
In this example, the operateOnNumbers function takes factorial(n - 1, n * acc)
two parameters a and b of type Int, and a third }
parameter operation of type (Int, Int) → Int. The }
operation parameter represents a function that
takes two Int parameters and returns an Int result.
In this example, the factorial function is defined as
Here’s an example of calling the operateOnNumbers tail recursive using the tailrec modifier. The
higher-order function: function takes two parameters n and acc, where n
represents the number for which factorial is
calculated, and acc represents the accumulated
val sum = operateOnNumbers(3, 4) { result. The function calculates the factorial of n
a, b -> using a tail recursive approach.

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


19 STARTING WITH KOTLIN

Tail recursive functions can be called like any other methods.


function:
Here’s an example of a simple class that represents
a person:
val result = factorial(5)
println(result) // Output: 120
class Person {
var name: String = ""
In this example, we call the factorial function with var age: Int = 0
the argument 5. The function calculates the
factorial of 5 using a tail recursive approach and
fun speak() {
returns the result, which is assigned to the result
println("Hello, my name is
variable. Finally, we print the value of result,
which outputs 120.
$name and I'm $age years old.")
}
Using tail recursive functions can help prevent }
stack overflow errors for recursive computations
that involve large input values.
In this example, we define a class named Person.
Functions are a powerful feature in Kotlin that The class has two properties: name, which is of type
allow you to encapsulate code, organize logic, and String, and age, which is of type Int. The class also
promote code reuse. Understanding how to define has a method named speak, which prints a greeting
and use functions is essential for writing clean and message using the values of the name and age
maintainable Kotlin code. properties.

To create an object of a class, you can use the new


CLASSESAND
CLASSES ANDOBJECTS
OBJECTS
keyword followed by the class name and
parentheses:
Classes and objects are the basic building blocks of
object-oriented programming in Kotlin. They allow
you to define blueprints for creating objects and val person = Person()
encapsulate data and behavior. In this section, we’ll
explore how to define classes and objects, and how
to work with them in Kotlin. In this example, we create an object of the Person
class and assign it to the person variable.

CLASSES
You can access the properties and methods of an
object using the dot notation:
A class is a blueprint for creating objects. It defines
the properties and behavior that objects of the class
will have. In Kotlin, classes are defined using the
person.name = "John"
class keyword, followed by the class name, an
person.age = 25
optional primary constructor, and a body enclosed
in curly braces.
person.speak() // Output: "Hello, my
name is John and I'm 25 years old."
Here’s the general syntax of a class declaration:

In this example, we set the name and age properties


class ClassName { of the person object and call the speak method,
which prints a greeting message.
// Properties
// Methods
} CONSTRUCTORS

A constructor is a special member function that is


In this syntax, ClassName is the name of the class. used to initialize the properties of a class when an
Inside the class body, you can define properties and object is created. In Kotlin, classes can have one

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


20 STARTING WITH KOTLIN

primary constructor and one or more secondary var name: String = ""
constructors. var age: Int = 0

Primary Constructor constructor(name: String, age:


Int) {
The primary constructor is part of the class header
this.name = name
and is defined after the class name. It can have
this.age = age
parameters, which are used to initialize the
}
properties of the class.

Here’s an example of a class with a primary fun speak() {


constructor: println("Hello, my name is
$name and I'm $age years old.")
}
class Person(name: String, age: Int)
}
{
var name: String = name
var age: Int = age In this example, the Person class has a secondary
constructor that takes the name and age parameters.
The secondary constructor initializes the name and
fun speak() {
age properties of the class.
println("Hello, my name is
$name and I'm $age years old.") To create an object of a class with a secondary
} constructor, you can use the new keyword followed
} by the class name and the constructor arguments:

In this example, the Person class has a primary val person = Person("John", 25)
constructor that takes two parameters: name of type
String and age of type Int. The primary constructor
initializes the name and age properties of the class. In this example, we create an object of the Person
class with the name and age constructor arguments.
To create an object of a class with a primary
constructor, you can use the new keyword followed
INHERITANCE
by the class name and the constructor arguments:
Inheritance is a mechanism that allows a class to
inherit properties and behavior from another class.
val person = Person("John", 25) In Kotlin, classes can inherit from other classes
using the : superclass() syntax.
In this example, we create an object of the Person
Here’s an example of a class that inherits from
class with the name and age constructor arguments.
another class:

Secondary Constructors
open class Animal {
Secondary constructors are additional constructors
open fun speak() {
that can be defined inside a class. They are defined
println("The animal makes a
using the constructor keyword and can have their
own parameters. sound.")
}
Here’s an example of a class with a secondary }
constructor:
class Dog : Animal() {
override fun speak() {
class Person {

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


21 STARTING WITH KOTLIN

println("The dog barks.") In this example, we define a data class named


} Person that has two properties: name of type String
and age of type Int. The val keyword before the
}
properties makes them read-only (immutable).

In this example, the Animal class is a base class that Data classes automatically generate the following
has a method named speak. The Dog class is a functions:
derived class that inherits from the Animal class
using the : Animal() syntax. The Dog class overrides • equals(other: Any?): Boolean: Compares two
the s peak method to provide its own objects for structural equality.
implementation. • hashCode(): Int: Calculates a hash code value
for the object.
To create an object of a derived class, you can use
the same syntax as creating an object of the base • toString(): String: Returns a string
class: representation of the object.

Data classes also provide a componentN function for


val dog = Dog() each property, which allows you to access the
properties using destructuring declarations.

In this example, we create an object of the Dog class Here’s an example of using a data class:
and assign it to the dog variable.

You can call the overridden method of the derived val person1 = Person("John", 25)
class using the dot notation: val person2 = Person("John", 25)

println(person1 == person2) //
dog.speak() // Output: "The dog
Output: true
barks."
val (name, age) = person1
In this example, we call the speak method of the dog println("Name: $name, Age: $age") //
object, which outputs "The dog barks.". The derived Output: "Name: John, Age: 25"
class overrides the method of the base class to
provide its own implementation.
In this example, we create two objects of the Person
Inheritance allows you to create class hierarchies data class with the same property values. We use
and promote code reuse by inheriting properties the == operator to compare the objects for equality,
and behavior from base classes. which returns true. Data classes automatically
generate the equals function based on the property
values.
DATA CLASSES

Data classes are special classes in Kotlin that are We also use a destructuring declaration to assign
used to hold data and automatically provide useful the property values of person1 to the name and age
functions such as equals, hashCode, and toString. variables. The component1() and component2()
Data classes are defined using the data keyword functions generated by the data class are used
before the class keyword. internally in the destructuring declaration.

Here’s an example of a data class: Data classes are useful when you need to define
classes that primarily hold data and want to
leverage the automatic generation of useful
data class Person(val name: String, functions.
val age: Int)

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


22 STARTING WITH KOTLIN

OBJECT DECLARATIONS }
}
Object declarations are a way to define a singleton
object, which is a class that has only one instance.
In Kotlin, you can define an object declaration using In this example, we define a class named MathUtils
the object keyword. with a companion object. The companion object has
a square function that calculates the square of a
Here’s an example of an object declaration: number.

You can call the functions of a companion object


object Logger { using the class name:
fun log(message: String) {
println("Log: $message")
val result = MathUtils.square(5)
}
println(result) // Output: 25
}

In this example, we call the square function of the


In this example, we define an object declaration
MathUtils companion object using the class name
named Logger. The Logger object has a log function
MathUtils. The function calculates the square of 5
that prints a log message.
and returns the result, which is assigned to the
You can call the functions of an object declaration result variable. Finally, we print the value of
directly: result, which outputs 25.

Companion objects are useful when you want to


Logger.log("Hello, World!") // define utility functions or constants that are
Output: "Log: Hello, World!" associated with a class.

Classes and objects are the fundamental building


In this example, we call the log function of the blocks of object-oriented programming in Kotlin.
Logger object, which prints the log message "Hello, Understanding how to define and work with classes
World!". and objects is essential for creating reusable and
modular code.
Object declarations are a convenient way to define
singleton objects without explicitly creating a class NULLSAFETY
NULL SAFETY
and instantiating it.
Null safety is a feature in Kotlin that helps prevent
COMPANION OBJECTS null pointer exceptions, which are a common
source of bugs in many programming languages.
Companion objects are objects that are associated Kotlin provides a type system that distinguishes
with a class and can access its private members. In between nullable and non-nullable types, and
Kotlin, you can define a companion object inside a enforces null safety through the use of safe calls
class using the companion keyword. and null checks. In this section, we’ll explore the
null safety features in Kotlin and how to use them
Here’s an example of a class with a companion effectively.
object:

NULLABLE AND NON-NULLABLE TYPES


class MathUtils {
In Kotlin, there are two kinds of types: nullable
companion object { types and non-nullable types.
fun square(number: Int): Int
{ A nullable type is denoted by adding a ? after the
return number * number type name. A nullable type can hold a value of its
} underlying type or null. For example, String? is a

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


23 STARTING WITH KOTLIN

nullable type that can hold a String value or null. length property.

A non-nullable type does not allow null values. If Safe calls provide a convenient way to access
you declare a variable with a non-nullable type, you properties and call methods on nullable objects
must initialize it with a non-null value. For without the need for explicit null checks.
example, String is a non-nullable type that can only
hold non-null String values. ELVIS OPERATOR

Here’s an example that demonstrates nullable and The Elvis operator ?: is used to provide a default
non-nullable types: value when a nullable expression is null. The Elvis
operator can be used in conjunction with safe calls
to handle nullable expressions.
val nullableString: String? = null
val nonNullableString: String = Here’s an example that demonstrates the Elvis
"Hello, World!" operator:

println(nullableString) // Output:
null val nullableString: String? = null
println(nonNullableString) //
Output: "Hello, World!" val length = nullableString?.length
?: 0

In this example, we declare a variable println(length) // Output: 0


nullableString of type String? and initialize it with
null. The variable can hold a String value or null.
We also declare a variable nonNullableString of type In this example, we use the Elvis operator ?: to
String and initialize it with the non-null value provide a default value of 0 when the
"Hello, World!". nullableString is null. If the nullableString is not
null, the safe call expression
nullableString?.length returns the value of the
SAFE CALLS
length property. Otherwise, if the nullableString is
Safe calls are a way to safely access properties and null, the Elvis operator expression returns 0.
call methods on nullable objects. In Kotlin, you can
The Elvis operator is a concise way to handle
use the safe call operator ?. to perform safe calls.
nullable expressions and provide default values
Here’s an example that demonstrates safe calls: when necessary.

NON-NULL ASSERTION
val nullableString: String? = null
The non-null assertion operator !! is used to assert
val length = nullableString?.length that a nullable expression is not null. If the nullable
expression is null, a NullPointerException is
println(length) // Output: null thrown.

Here’s an example that demonstrates the non-null


In this example, we have a nullable variable assertion operator:
nullableString that is initialized with null. We use
the safe call operator ?. to access the length
property of the nullableString variable. If the val nullableString: String? = null
nullableString is null, the safe call expression
returns null, and the length variable is assigned val length = nullableString!!.length
null. Otherwise, if the nullableString is not null,
the safe call expression returns the value of the println(length) // Throws

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


24 STARTING WITH KOTLIN

NullPointerException define and use extensions and lambdas in Kotlin.

EXTENSIONS
In this example, we use the non-null assertion
operator !! to assert that the nullableString is not
Extensions allow you to add new functions and
null before accessing its length property. If the properties to existing classes without modifying
nullableString is null, a NullPointerException is their source code. Extensions are defined outside
thrown. the class they extend and can be called on instances
of the extended class.
The non-null assertion operator should be used
with caution, as it can lead to runtime exceptions if Here’s the general syntax of an extension function:
used improperly. It should only be used when you
are certain that the nullable expression is not null.
fun
SAFE CASTS ClassName.functionName(parameters):
returnType {
Safe casts are used to cast an object to a nullable // Code to execute
type when the cast may fail. In Kotlin, you can use
}
the safe cast operator as? to perform safe casts.

Here’s an example that demonstrates safe casts: In this syntax, ClassName is the name of the class
being extended, functionName is the name of the
extension function, parameters is the optional
val obj: Any = "Hello, World!" comma-separated list of input parameters, and
returnType is the return type of the function.
val string: String? = obj as? String
Here’s an example of an extension function that
println(string) // Output: "Hello, calculates the square of an Int:
World!"
fun Int.square(): Int {
In this example, we have an object obj of type Any return this * this
that holds a String value. We use the safe cast }
operator as? to cast obj to the nullable type String?.
If the cast is successful, the safe cast expression
returns the value of obj as a String. Otherwise, if In this example, we define an extension function
the cast fails, the safe cast expression returns null. square for the Int class. The extension function can
be called on instances of the Int class and calculates
Safe casts provide a way to safely cast objects and the square of the value.
handle cases where the cast may fail.
Here’s an example of calling the square extension
Null safety is an important feature in Kotlin that function:
helps prevent null pointer exceptions. By using
nullable and non-nullable types, safe calls, the Elvis
operator, non-null assertions, and safe casts, you val number = 5
can write more robust and error-free code. val result = number.square()
println(result) // Output: 25
EXTENSIONSAND
EXTENSIONS ANDLAMBDAS
LAMBDAS
In this example, we call the square extension
Extensions and lambdas are powerful features in function on the number variable of type Int. The
Kotlin that allow you to add new functionality to extension function calculates the square of the
existing classes and work with functions as first- value 5 and returns the result, which is assigned to
class citizens. In this section, we’ll explore how to the result variable. Finally, we print the value of

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


25 STARTING WITH KOTLIN

result, which outputs 25. Here’s the general syntax of a lambda:

Extensions provide a way to add new functionality


to existing classes and promote code reuse without val lambdaName: (parameters) ->
modifying the original class. returnType = { arguments ->

EXTENSION PROPERTIES
// Code to execute
In addition to extension functions, Kotlin also }
allows you to define extension properties, which
are similar to regular properties but are added to
existing classes. In this syntax, lambdaName is the name of the lambda
(optional), parameters is the optional comma-
Here’s an example of an extension property: separated list of input parameters, returnType is the
return type of the lambda (optional), and arguments
is the body of the lambda.
val String.hasUppercase: Boolean
get() = this.any { Here’s an example of a lambda that adds two
it.isUpperCase() } numbers:

In this example, we define an extension property val add: (Int, Int) -> Int = { a, b
hasUppercase for the String class. The extension ->
property is defined using the val keyword, followed a + b
by the property name hasUppercase. The get()
}
function is the getter function that returns the
value of the property.
In this example, we define a lambda named add that
Here’s an example of accessing the extension takes two Int parameters and returns their sum.
property:
Here’s an example of calling the lambda:

val text = "Hello, World!"


val result = add(3, 4)
println(text.hasUppercase) // println(result) // Output: 7
Output: true
In this example, we call the add lambda with the
In this example, we access the hasUppercase arguments 3 and 4. The lambda adds the two
extension property on the text variable of type numbers and returns the sum, which is assigned to
String. The extension property checks whether the the result variable. Finally, we print the value of
string contains any uppercase characters and result, which outputs 7.
returns true if it does.
Lambdas are often used with higher-order
Extension properties provide a way to add functions to provide concise and expressive code.
additional properties to existing classes, enhancing
their functionality. HIGHER-ORDER FUNCTIONS

Higher-order functions are functions that can


LAMBDAS
accept other functions as parameters or return
Lambdas are anonymous functions that can be functions as results. Higher-order functions are a
treated as values and passed around in your code. key feature of functional programming and enable
In Kotlin, you can define lambdas using a you to write code that is more concise and
lightweight syntax. expressive.

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


26 STARTING WITH KOTLIN

Here’s an example of a higher-order function that programming language, and Kotlin provides a rich
takes a function as a parameter: set of collection classes and functions. In this
section, we’ll explore the different types of
collections available in Kotlin and how to work
fun operateOnNumbers(a: Int, b: Int, with them effectively.
operation: (Int, Int) -> Int): Int {
return operation(a, b) LISTS
}
Lists are ordered collections of elements, where
each element has an index. In Kotlin, you can create
In this example, the operateOnNumbers function takes lists using the listOf() function or the
two parameters a and b of type Int, and a third mutableListOf() function if you need to modify the
parameter operation of type (Int, Int) → Int. The list.
operation parameter represents a function that
takes two Int parameters and returns an Int result. Here’s an example of creating a list and accessing
its elements:
Here’s an example of calling the operateOnNumbers
higher-order function:
val fruits = listOf("Apple",
"Banana", "Orange")
val sum = operateOnNumbers(3, 4) {
a, b ->
println(fruits[0]) // Output:
a + b
"Apple"
}
println(fruits[1]) // Output:
"Banana"
val product = operateOnNumbers(5, 6)
println(fruits[2]) // Output:
{ a, b ->
"Orange"
a * b
}
In this example, we create a list of fruits using the
listOf() function. We can access the elements of
In this example, we call the operateOnNumbers the list using the index in square brackets.
function twice, passing different functions as the
operation parameter. The first call calculates the Lists are immutable by default, which means you
sum of 3 and 4 using a lambda expression, and the cannot add or remove elements once the list is
second call calculates the product of 5 and 6 using created. If you need to modify the list, you can use
another lambda expression. the mutableListOf() function instead:

Higher-order functions enable you to write more


generic and reusable code by abstracting the val mutableFruits =
behavior of a function and allowing it to be mutableListOf("Apple", "Banana",
customized at runtime. "Orange")
Extensions and lambdas are powerful features in
mutableFruits.add("Mango")
Kotlin that enable you to extend existing classes
with new functionality and work with functions as
mutableFruits.removeAt(1)
first-class citizens. By using extensions and
lambdas, you can write code that is more modular, println(mutableFruits) // Output:
reusable, and expressive. ["Apple", "Orange", "Mango"]

COLLECTIONS
COLLECTIONS In this example, we create a mutable list of fruits
using the mutableListOf() function. We can add
Collections are a fundamental part of any
elements to the list using the add() method and

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


27 STARTING WITH KOTLIN

remove elements using the removeAt() method. MAPS

Lists provide an ordered collection of elements and Maps are collections of key-value pairs, where each
are useful when you need to maintain the order of key is unique. In Kotlin, you can create maps using
elements or access elements by index. the mapOf() function or the mutableMapOf() function
if you need to modify the map.

SETS
Here’s an example of creating a map and accessing
Sets are collections of unique elements with no its values using keys:
defined order. In Kotlin, you can create sets using
the setOf() function or the mutableSetOf() function
val fruits = mapOf(
if you need to modify the set.
"apple" to "red",
Here’s an example of creating a set and accessing "banana" to "yellow",
its elements: "orange" to "orange"
)

val numbers = setOf(1, 2, 3, 4, 5)


println(fruits["apple"]) // Output:
"red"
println(numbers.contains(3)) //
println(fruits["banana"]) // Output:
Output: true
"yellow"
println(numbers.contains(6)) //
println(fruits["orange"]) // Output:
Output: false
"orange"

In this example, we create a set of numbers using


In this example, we create a map of fruits and their
the setOf() function. We can check if an element is
corresponding colors using the mapOf() function. We
present in the set using the contains() method.
can access the values of the map using the keys in
square brackets.
Sets are immutable by default, but if you need to
modify the set, you can use the mutableSetOf()
Maps are immutable by default, but if you need to
function:
modify the map, you can use the mutableMapOf()
function:

val mutableNumbers = mutableSetOf(1,


2, 3, 4, 5) val mutableFruits = mutableMapOf(

mutableNumbers.add(6)
mutableNumbers.remove(3) "apple" to "red",
"banana" to "yellow",
println(mutableNumbers) // Output: "orange" to "orange"
[1, 2, 4, 5, 6] )

In this example, we create a mutable set of mutableFruits["grape"] = "purple"


numbers using the mutableSetOf() function. We can mutableFruits.remove("apple")
add elements to the set using the add() method and
remove elements using the remove() method. println(mutableFruits) // Output:
{banana=yellow, orange=orange,
Sets are useful when you need to maintain a
grape=purple}
collection of unique elements and don’t require a
specific order.
In this example, we create a mutable map of fruits

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


28 STARTING WITH KOTLIN

and their colors using the mutableMapOf() function.


We can add key-value pairs to the map using the fun main() {
square bracket syntax and the assignment operator, GlobalScope.launch {
and remove key-value pairs using the remove() // Code to execute in the
method. coroutine
}
Maps are useful when you need to associate values
with unique keys and perform efficient key-based
lookups. // Code to execute outside the
coroutine
Collections are a powerful tool in Kotlin that allow
you to store, access, and manipulate groups of Thread.sleep(1000) // Wait for
related data. By understanding the different types the coroutine to finish
of collections and how to work with them, you can }
write code that is more organized and efficient.

COROUTINES
COROUTINES
In this example, we use the launch function from
GlobalScope to start a new coroutine. The code
Coroutines are a powerful concurrency framework inside the coroutine will execute concurrently with
in Kotlin that allow you to write asynchronous code the code outside the coroutine. We use
in a sequential and structured manner. Coroutines Thread.sleep(1000) to wait for the coroutine to
enable non-blocking, concurrent programming finish before the program exits.
without the complexities of traditional multi-
threading. In this section, we’ll explore how to use SUSPENDING FUNCTIONS
coroutines in Kotlin to write asynchronous and
concurrent code. Suspending functions are functions that can be
suspended and resumed later without blocking the
execution of other coroutines. Suspending
INTRODUCTION TO COROUTINES
functions are defined using the suspend modifier.
Coroutines are lightweight threads that can be
Here’s an example of a suspending function:
suspended and resumed at specific points without
blocking the execution of other coroutines.
Coroutines provide a way to write asynchronous
import kotlinx.coroutines.delay
code that looks like sequential code, making it
easier to reason about and maintain.
suspend fun doWork() {
To use coroutines in Kotlin, you need to add the delay(1000) // Simulate some
kotlinx.coroutines dependency to your project. work
Coroutines are part of the Kotlin standard library println("Work completed")
and provide a rich set of functions and utilities for }
asynchronous programming.

In this example, we define a suspending function


LAUNCHING COROUTINES
doWork using the suspend modifier. The function
suspends for 1000 milliseconds using the delay
To launch a new coroutine, you can use the launch
function from the kotlinx.coroutines library,
function provided by the kotlinx.coroutines library.
simulating some work. After the suspension, it
The launch function starts a new coroutine that
prints a message indicating that the work is
runs concurrently with the rest of the code.
completed.
Here’s an example of launching a coroutine:
Suspending functions can only be called from
within a coroutine or another suspending function.
import kotlinx.coroutines.*

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


29 STARTING WITH KOTLIN

COROUTINE CONTEXT AND execute on a separate thread from the default pool.
DISPATCHERS The code outside the coroutine will execute on the
main thread.
Coroutines run in a specific context, which defines
the execution environment for the coroutine. The
ASYNC/AWAIT
context includes the dispatcher, which determines
the thread or thread pool on which the coroutine The async function is used to perform concurrent
runs. computations and await the result of a coroutine.
The async function returns a Deferred object, which
In Kotlin, the Dispatchers object provides a set of represents a future value or a promise.
dispatchers that define different execution
environments for coroutines: Here’s an example of using async and await:

• Dispatchers.Default: Uses a shared pool of


threads for CPU-intensive work. import kotlinx.coroutines.*
• Dispatchers.IO: Uses a shared pool of threads
for I/O-bound work, such as file I/O and suspend fun getRemoteData(): String
network requests. {
delay(1000) // Simulate fetching
• Dispatchers.Main: Uses the main thread for UI-
related work in Android applications.
remote data
return "Remote Data"
• Dispatchers.Unconfined: Runs the coroutine in
}
the caller thread until the first suspension
point.
fun main() = runBlocking {
You can specify the dispatcher for a coroutine using val deferred = async {
the CoroutineScope or the withContext function. getRemoteData() }

Here’s an example of specifying a dispatcher using // Code to execute outside the


CoroutineScope: coroutine

val result = deferred.await()


import kotlinx.coroutines.*
println(result) // Output:
"Remote Data"
fun main() = runBlocking {
}
launch(Dispatchers.Default) {
// Code to execute in the
coroutine In this example, we define a suspending function
} getRemoteData that simulates fetching remote data.
We use the async function to start a new coroutine
// Code to execute outside the that invokes the getRemoteData function. The async
coroutine function returns a Deferred object, which
represents the result of the coroutine. We use the
await function to wait for the completion of the
delay(1000) // Wait for the
coroutine and retrieve the result.
coroutine to finish
} Async/await is a powerful pattern that allows you to
perform concurrent computations and wait for
their results without blocking the execution of
In this example, we use the launch function from
other coroutines.
the CoroutineScope provided by runBlocking to start
a new coroutine with the Dispatchers.Default
Coroutines are a versatile tool for writing
dispatcher. The code inside the coroutine will
asynchronous and concurrent code in Kotlin. By

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!


30 STARTING WITH KOTLIN

using coroutines, you can write code that is more Resource Description
structured, sequential, and easier to reason about.
Kotlin GitHub GitHub repository for
Coroutines provide a rich set of functions and
Repository the Kotlin programming
utilities for handling concurrency, such as
language. Contains the
launching coroutines, suspending functions,
source code, issue
specifying dispatchers, and using async/await for
tracker, and community
concurrent computations.
contributions.

RESOURCES
RESOURCES Kotlin Forum Official forum for Kotlin.
A place to ask questions,
These resources provide a comprehensive starting share knowledge, and
point for learning and working with Kotlin. They engage with the Kotlin
cover official documentation, community-driven community.
content, online tools, and helpful forums. Feel free
Kotlin Blog Official blog for Kotlin.
to explore them based on your specific needs and
Provides updates,
interests.
tutorials, and articles on
various Kotlin topics.
Resource Description
Kotlin Weekly A weekly newsletter
Kotlin Programming Official website for featuring curated Kotlin
Language Kotlin programming news, articles, libraries,
language. Provides and events.
documentation,
tutorials, and reference Awesome Kotlin A curated list of Kotlin
material. libraries, frameworks,
and other resources.
Kotlin Koans Interactive online Includes various
exercises to learn Kotlin categories to explore
concepts and syntax. and find useful Kotlin
Kotlin Standard Library Documentation for the tools.
Kotlin Standard Library, Kotlin for Android Official documentation
which includes a wide Developers and resources for using
range of utility functions Kotlin in Android
and classes. development. Includes
Kotlin Coroutines Guide Official guide for Kotlin guides, samples, and
coroutines. Covers the migration information.
basics, advanced topics,
and best practices for
working with
coroutines.

JCG delivers over 1 million pages each month to more than 700K software
developers, architects and decision makers. JCG offers something for everyone,
including news, tutorials, cheat sheets, research guides, feature articles, source code
and more.
CHEATSHEET FEEDBACK
WELCOME
support@javacodegeeks.com

Copyright © 2014 Exelixis Media P.C. All rights reserved. No part of this publication may be SPONSORSHIP
reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, OPPORTUNITIES
mechanical, photocopying, or otherwise, without prior written permission of the publisher. sales@javacodegeeks.com

JAVACODEGEEKS.COM | © EXELIXIS MEDIA P.C. VISIT JAVACODEGEEKS.COM FOR MORE!

You might also like