This document provides examples of Kotlin programming concepts including:
- Null safety checks using safe calls (?.) and Elvis operator (?:) to handle null values.
- Smart casts that allow treating a variable as a more specific type after checking its type in an if statement.
- String templates using $ variable interpolation to embed values in strings.
- Range expressions using .., downTo, and step operators to iterate over a range of values.
- Higher order functions like let, apply, use, with that take functions as parameters and help scope variables or simplify code.
- When expressions as a replacement for switch/case with more powerful pattern matching capabilities.
- Functions for mutable and
39. String templates
val apples = 4
val bananas = 3
println("I have $apples apples and " + (apples + bananas) + " fruits.")
> I have 4 apples.
> I have 4 apples.
> I have 4 apples and 7 fruits.
40. String templates
val apples = 4
val bananas = 3
println("I have $apples apples and ${apples+bananas} fruits.")
> I have 4 apples.
> I have 4 apples and 7 fruits.
> I have 4 apples and 7 fruits.
50. Range expressions
for (i in 1.0..2.0 step 0.3) {
print("$i ")
}
> 42
> 1.0 2.0
> 1.0 1.3 1.6 1.9
51. Lab 1
Foo Corporation needs a program to calculate how much to pay their hourly employees. The US Department
of Labor requires that employees get paid time and a half for any hours over 40 that they work in a single
week. For example, if an employee works 45 hours, they get 5 hours of overtime, at 1.5 times their base pay.
The State of Massachusetts requires that hourly employees be paid at least $8.00 an hour. Foo Corp requires
that an employee not work more than 60 hours in a week.
• Rules
• An employee gets paid (hours worked) × (base pay), for each hour up to 40 hours.
• For every hour over 40, they get overtime = (base pay) × 1.5.
• The base pay must not be less than the minimum wage ($8.00 an hour). If it is, print an error.
• If the number of hours is greater than 60, print an error message.
Write a method that takes the base pay and hours worked as parameters, and prints the total pay
or an error. Write a main method that calls this method for each of these employees:
Base Pay Hours Worked
Employee 1 $7.50 35
Employee 2 $8.20 47
Employee 3 $10.00 73
52. Lab 2
A group of ITI friends decide to run a Marathon. Their names and times (in minutes) are below:
Name Time (minutes)
Ahmed 341
Mohamed 273
Ismail 278
Hend 329
Aly 445
Hossam 402
Ola 388
Alaa 275
Basma 243
Mina 334
Nada 412
Saad 393
• Find the fastest runner. Print the name and his/her time (in minutes).
• Optional: Find the second fastest runner. Print the name and his/her time (in minutes).
53. Lab 3
• Create an Android a simple app with two buttons, one to count and
one to show a toast.
54. Lab 4
• Create an Android UI with one text field, centered at the top of the screen, and
one button. The text field will initially display the text Tap to Change Color.
• Every time you tap the button, you will generate a random color using RGB
values, change the text to that color, and display the values for the color in the
following format (assuming you are displaying a light grey with values
100/100/100): COLOR: 100r, 100g, 100b.
55. Lab 5
• Battery Status App
• Create an Android App that displays a colored
bar to display the battery's status.
• Display a battery drawable as follows:
0-25% - Red (battery low)
>25% <80% - Yellow (battery medium)
>80% - Green (battery good)
59. When expression
when (argument) {
m a t c h 1 - > f u n 1 ( )
m a t c h 2 - > f u n 2 ( )
e l s e - > f u n 3 ( )
}
Can be anything
60. When expression
( a r g u m e n t )
Match1 -> fun1()
match2 -> fun2()
e l s e - > f u n 3 ( )
}
Can be anything
61. When expression
var result: Int = when (argument) {
m a t c h 1 - > f u n 1 ( )
m a t c h 2 - > f u n 2 ( )
e l s e - > f u n 3 ( )
}
Can return result
63. When expression
override fun onCreateViewHolder(g: ViewGroup, type: Int) {
when (type) {
TYPE_TITLE -> TitleViewHolder(g)
TYPE_DESCRIPTION -> DescriptionViewHolder(g))
}
return null
}
64. When expression
o v e r r i d e f u n o n C r e a t e V i e w H o l d e r ( g : V i e w G r o u p ,
t y p e : I n t ) {
when (type) {
T Y P E _ T I T L E - > T i t l e V i e w H o l d e r ( g )
T Y P E _ D E S C R I P T I O N - >
D e s c r i p t i o n V i e w H o l d e r ( g ) )
}
r e t u r n n u l l
}
Can be placed after a = symbol
65. When expression
override fun onCreateViewHolder(g: ViewGroup, type: Int) = when (type) {
T Y P E _ T I T L E - > T i t l e V i e w H o l d e r ( g )
T Y P E _ D E S C R I P T I O N - >
D e s c r i p t i o n V i e w H o l d e r ( g ) )
e l s e - > n u l l
}
66. When expression
override fun onCreateViewHolder(g: ViewGroup, type: Int) = when (type) {
TYPE_TITLE -> TitleViewHolder(g)
TYPE_DESCRIPTION -> DescriptionViewHolder(g)
else -> null
}
67. When expression
override fun getItemViewType(index: Int) = when (dataList[index]) {
is Title -> TYPE_TITLE
is Description -> TYPE_DESCRIPTION
else -> TYPE_UNDEFINED
}
68. When expression
override fun getItemViewType(index: Int) = when (dataList[index]) {
is Title -> TYPE_TITLE
is Description -> TYPE_DESCRIPTION
else -> TYPE_UNDEFINED
}
Type checks possible
69. When expression
override fun getItemViewType(index: Int) = when (dataList[index]) {
is Title -> TYPE_TITLE
is Description -> TYPE_DESCRIPTION
else -> TYPE_UNDEFINED
}
70. When expression
override fun onBindViewHolder(viewHolder: ViewHolder, index: Int) {
val displayable: Displayable = dataList[index]
when (displayable) {
is Title -> initTitle(viewHolder, displayable)
is Description -> initDescription(viewHolder, displayable)
}
}
71. When expression
o v e r r i d e f u n o n B i n d V i e w H o l d e r ( v i e w H o l d e r : V i e w H o l d e r , i n d e x : I n t ) {
v a l d i s p l a y a b l e : D i s p l a y a b l e = d a t a L i s t [ i n d e x ]
W h e n ( d i s p l a y a b l e ) {
is Title -> initTitle(viewHolder, displayable)
is Description -> initDescription(viewHolder, displayable)
}
}
Smart cast
73. let, apply, use, with
• Higher-order functions - function that takes
functions as parameters, or returns a function.
74. let (scope function)
/**
* Calls the specified function [block] with `this` value as
* its argument and returns its result.
*/
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
80. use (try with resources function)
/**
* Executes the given [block] function on this resource and then
* closes it down correctly whether an exception is thrown or not.
*/
public inline fun <T : Closeable, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Exception) {
// ommitted
} finally {
if (!closed) { close()
}
}
}
81. use
fun countUsers(): Long {
val database = openDatabase()
val result = database.count("users")
database.close()
return result
}
82. use
fun countUsers() = openDatabase().use { it.count("users") }
Automatically close
database
83. fun countUsers() = openDatabase().use { it.count("users") }
Refers to database object
use
85. with
/**
* Calls the specified function [block] with the given [receiver]
* as its receiver and returns its result.
*/
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
91. apply
/**
* Calls the specified function [block] with `this` value as its receiver
* and returns `this` value.
*/
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
102. Default values for function parameters
• Function parameters can have default values, which are used when a
corresponding argument is omitted.
• This allows for a reduced number of overloads compared to other
languages.
103. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String?,
selectionArgs : Array<String>?,
orderBy: String?): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), null, null, "NAME")
104. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String? = null,
selectionArgs : Array<String>? = null,
orderBy: String? = null): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), null, null, "NAME")
Default value
105. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String? = null,
selectionArgs : Array<String>? = null,
orderBy: String? = null): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), null, null, "NAME")
106. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String? = null,
selectionArgs : Array<String>? = null,
orderBy: String? = null): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), null, null, orderBy = "NAME")
Named argument
107. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String? = null,
selectionArgs : Array<String>? = null,
orderBy: String? = null): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), null, null, orderBy = "NAME")
Not needed
108. Default values for function parameters
fun query(table: String,
columns: Array<String>,
selection: String? = null,
selectionArgs : Array<String>? = null,
orderBy: String? = null): Cursor {
...
}
// function call
query("USERS", arrayOf("ID", "NAME"), orderBy = "NAME")
111. Lazy property
val preference = getSharedPreferences("pref")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val username = preference.getString("username")
}
112. Lazy property
val preference = getSharedPreferences("pref")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val username = preference.getString("username")
}
Crash, require context
113. Lazy property
val preference by lazy { getSharedPreferences("pref") }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val username = preference.getString("username")
}
Won’t be executed until the
property is first used
114. Lazy property
val preference by lazy { getSharedPreferences("pref") }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val username = preference.getString("username")
}
121. Extension functions
public fun Int.isLollipopOrGreater(): Boolean {.
return this >= Build.VERSION_CODES.LOLLIPOP
}
if (Build.VERSION.SDK_INT.isLollipopOrGreater) {
// ...
}
122. Extension functions
public fun Int.isLollipopOrGreater(): Boolean {.
return this >= Build.VERSION_CODES.LOLLIPOP
}
if (16.isLollipopOrGreater) {
// ...
}
151. Data class
What it does?
Nothing, just hold data
What it provides?
● getters, setters
● equals()/hashCode()
● toString() ofthe form"User(name=John, age=42)"
● copy() function