Kotlin Notes
Kotlin Notes
KOTLIN BASIC TO
ADVANCED
APP DEVELOPMENT
WWW.LEARNLONER.COM
Contents
About ................................................................................................................................................................................... 1
Chapter 1: Getting started with Kotlin ............................................................................................................... 2
Section 1.1: Hello World ................................................................................................................................................. 2
Section 1.2: Hello World using a Companion Object .................................................................................................. 2
Section 1.3: Hello World using an Object Declaration ................................................................................................ 3
Section 1.4: Main methods using varargs .................................................................................................................... 4
Section 1.5: Compile and Run Kotlin Code in Command Line ................................................................................... 4
Section 1.6: Reading input from Command Line ........................................................................................................ 4
Chapter 2: Basics of Kotlin ....................................................................................................................................... 6
Section 2.1: Basic examples .......................................................................................................................................... 6
Chapter 3: Strings ......................................................................................................................................................... 7
Section 3.1: String Equality ............................................................................................................................................ 7
Section 3.2: String Literals ............................................................................................................................................ 7
Section 3.3: Elements of String ..................................................................................................................................... 8
Section 3.4: String Templates ....................................................................................................................................... 8
Chapter 4: Arrays ......................................................................................................................................................... 9
Section 4.1: Generic Arrays ........................................................................................................................................... 9
Section 4.2: Arrays of Primitives .................................................................................................................................. 9
Section 4.3: Create an array ........................................................................................................................................ 9
Section 4.4: Create an array using a closure ............................................................................................................. 9
Section 4.5: Create an uninitialized array ................................................................................................................... 9
Section 4.6: Extensions ................................................................................................................................................ 10
Section 4.7: Iterate Array ............................................................................................................................................ 10
Chapter 5: Collections .............................................................................................................................................. 11
Section 5.1: Using list ................................................................................................................................................... 11
Section 5.2: Using map ............................................................................................................................................... 11
Section 5.3: Using set .................................................................................................................................................. 11
Chapter 6: Enum .......................................................................................................................................................... 12
Section 6.1: Initialization .............................................................................................................................................. 12
Section 6.2: Functions and Properties in enums ...................................................................................................... 12
Section 6.3: Simple enum ............................................................................................................................................ 12
Section 6.4: Mutability ................................................................................................................................................. 12
Chapter 7: Functions ................................................................................................................................................. 14
Section 7.1: Function References ............................................................................................................................... 14
Section 7.2: Basic Functions ....................................................................................................................................... 15
Section 7.3: Inline Functions ....................................................................................................................................... 16
Section 7.4: Lambda Functions .................................................................................................................................. 16
Section 7.5: Operator functions ................................................................................................................................. 16
Section 7.6: Functions Taking Other Functions ........................................................................................................ 17
Section 7.7: Shorthand Functions .............................................................................................................................. 17
Chapter 8: Vararg Parameters in Functions ................................................................................................ 18
Section 8.1: Basics: Using the vararg keyword ......................................................................................................... 18
Section 8.2: Spread Operator: Passing arrays into vararg functions .................................................................... 18
Chapter 9: Conditional Statements ................................................................................................................... 19
Section 9.1: When-statement argument matching .................................................................................................. 19
Section 9.2: When-statement as expression ............................................................................................................ 19
LearnLoner.com
LearnLoner
Section 9.3: Standard if-statement ............................................................................................................................ 19
Section 9.4: If-statement as an expression ............................................................................................................... 19
Section 9.5: When-statement instead of if-else-if chains ....................................................................................... 20
Section 9.6: When-statement with enums ................................................................................................................ 20
Chapter 10: Loops in Kotlin .................................................................................................................................... 22
Section 10.1: Looping over iterables ........................................................................................................................... 22
Section 10.2: Repeat an action x times ...................................................................................................................... 22
Section 10.3: Break and continue ............................................................................................................................... 22
Section 10.4: Iterating over a Map in kotlin ............................................................................................................... 23
Section 10.5: Recursion ............................................................................................................................................... 23
Section 10.6: While Loops ........................................................................................................................................... 23
Section 10.7: Functional constructs for iteration ...................................................................................................... 23
Chapter 11: Ranges ..................................................................................................................................................... 25
Section 11.1: Integral Type Ranges ............................................................................................................................. 25
Section 11.2: downTo() function .................................................................................................................................. 25
Section 11.3: step() function ........................................................................................................................................ 25
Section 11.4: until function ........................................................................................................................................... 25
Chapter 12: Regex ....................................................................................................................................................... 26
Section 12.1: Idioms for Regex Matching in When Expression ................................................................................ 26
Section 12.2: Introduction to regular expressions in Kotlin ..................................................................................... 27
Chapter 13: Basic Lambdas .................................................................................................................................... 30
Section 13.1: Lambda as parameter to filter function .............................................................................................. 30
Section 13.2: Lambda for benchmarking a function call ......................................................................................... 30
Section 13.3: Lambda passed as a variable .............................................................................................................. 30
Chapter 14: Null Safety ........................................................................................................................................... 31
Section 14.1: Smart casts ............................................................................................................................................. 31
Section 14.2: Assertion ................................................................................................................................................. 31
Section 14.3: Eliminate nulls from an Iterable and array ......................................................................................... 31
Section 14.4: Null Coalescing / Elvis Operator .......................................................................................................... 31
Section 14.5: Nullable and Non-Nullable types ......................................................................................................... 32
Section 14.6: Elvis Operator (?:) .................................................................................................................................. 32
Section 14.7: Safe call operator .................................................................................................................................. 32
Chapter 15: Class Delegation ................................................................................................................................ 34
Section 15.1: Delegate a method to another class ................................................................................................... 34
Chapter 16: Class Inheritance ............................................................................................................................... 35
Section 16.1: Basics: the 'open' keyword .................................................................................................................... 35
Section 16.2: Inheriting fields from a class ................................................................................................................ 35
Section 16.3: Inheriting methods from a class .......................................................................................................... 36
Section 16.4: Overriding properties and methods .................................................................................................... 36
Chapter 17: Visibility Modifiers ............................................................................................................................. 38
Section 17.1: Code Sample ........................................................................................................................................... 38
Chapter 18: Generics ................................................................................................................................................. 39
Section 18.1: Declaration-site variance ...................................................................................................................... 39
Section 18.2: Use-site variance ................................................................................................................................... 39
Chapter 19: Interfaces .............................................................................................................................................. 41
Section 19.1: Interface with default implementations ............................................................................................... 41
Section 19.2: Properties in Interfaces ......................................................................................................................... 42
Section 19.3: super keyword ....................................................................................................................................... 42
Section 19.4: Basic Interface ....................................................................................................................................... 42
LearnLoner.com
LearnLoner
Section 19.5: Conflicts when Implementing Multiple Interfaces with Default Implementations .......................... 43
Chapter 20: Singleton objects .............................................................................................................................. 44
Section 20.1: Use as replacement of static methods/fields of java ....................................................................... 44
Section 20.2: Use as a singleton ................................................................................................................................ 44
Chapter 21: coroutines ............................................................................................................................................. 45
Section 21.1: Simple coroutine which delay's 1 second but not blocks ................................................................... 45
Chapter 22: Annotations ......................................................................................................................................... 46
Section 22.1: Meta-annotations .................................................................................................................................. 46
Section 22.2: Declaring an annotation ...................................................................................................................... 46
Chapter 23: Type aliases ......................................................................................................................................... 47
Section 23.1: Function type ......................................................................................................................................... 47
Section 23.2: Generic type .......................................................................................................................................... 47
Chapter 24: Type-Safe Builders ......................................................................................................................... 48
Section 24.1: Type-safe tree structure builder .......................................................................................................... 48
Chapter 25: Delegated properties ..................................................................................................................... 49
Section 25.1: Observable properties .......................................................................................................................... 49
Section 25.2: Custom delegation ............................................................................................................................... 49
Section 25.3: Lazy initialization .................................................................................................................................. 49
Section 25.4: Map-backed properties ....................................................................................................................... 49
Section 25.5: Delegate Can be used as a layer to reduce boilerplate .................................................................. 49
Chapter 26: Reflection ............................................................................................................................................. 51
Section 26.1: Referencing a class ............................................................................................................................... 51
Section 26.2: Inter-operating with Java reflection .................................................................................................. 51
Section 26.3: Referencing a function ......................................................................................................................... 51
Section 26.4: Getting values of all properties of a class ......................................................................................... 51
Section 26.5: Setting values of all properties of a class .......................................................................................... 52
Chapter 27: Extension Methods ........................................................................................................................... 54
Section 27.1: Potential Pitfall: Extensions are Resolved Statically .......................................................................... 54
Section 27.2: Top-Level Extensions ........................................................................................................................... 54
Section 27.3: Lazy extension property workaround ................................................................................................ 54
Section 27.4: Sample extending Java 7+ Path class ............................................................................................... 55
Section 27.5: Sample extending long to render a human readable string ........................................................... 55
Section 27.6: Sample extending Java 8 Temporal classes to render an ISO formatted string .......................... 55
Section 27.7: Using extension functions to improve readability ............................................................................. 55
Section 27.8: Extension functions to Companion Objects (appearance of Static functions) .............................. 56
Section 27.9: Extensions for easier reference View from code .............................................................................. 57
Chapter 28: DSL Building ........................................................................................................................................ 58
Section 28.1: Infix approach to build DSL .................................................................................................................. 58
Section 28.2: Using operators with lambdas ............................................................................................................ 58
Section 28.3: Overriding invoke method to build DSL ............................................................................................. 58
Section 28.4: Using extensions with lambdas ........................................................................................................... 58
Chapter 29: Idioms ..................................................................................................................................................... 60
Section 29.1: Serializable and serialVersionUid in Kotlin ......................................................................................... 60
Section 29.2: Delegate to a class without providing it in the public constructor .................................................. 60
Section 29.3: Use let or also to simplify working with nullable objects ................................................................. 61
Section 29.4: Use apply to initialize objects or to achieve method chaining ........................................................ 61
Section 29.5: Fluent methods in Kotlin ...................................................................................................................... 61
Section 29.6: Filtering a list ......................................................................................................................................... 62
Section 29.7: Creating DTOs (POJOs/POCOs) ........................................................................................................ 62
LearnLoner.com
LearnLoner
Chapter 30: RecyclerView in Kotlin ................................................................................................................... 63
Section 30.1: Main class and Adapter ........................................................................................................................ 63
Chapter 31: logging in kotlin .................................................................................................................................. 65
Section 31.1: kotlin.logging .......................................................................................................................................... 65
Chapter 32: Exceptions ............................................................................................................................................. 66
Section 32.1: Catching exception with try-catch-finally ........................................................................................... 66
Chapter 33: JUnit ........................................................................................................................................................ 67
Section 33.1: Rules ........................................................................................................................................................ 67
Chapter 34: Kotlin Android Extensions ............................................................................................................ 68
Section 34.1: Using Views ............................................................................................................................................ 68
Section 34.2: Configuration ........................................................................................................................................ 68
Section 34.3: Painful listener for getting notice, when the view is completely drawn now is so simple and
awesome with Kotlin's extension ....................................................................................................................... 69
Section 34.4: Product flavors ..................................................................................................................................... 69
Chapter 35: Kotlin for Java Developers ......................................................................................................... 71
Section 35.1: Declaring Variables ............................................................................................................................... 71
Section 35.2: Quick Facts ............................................................................................................................................ 71
Section 35.3: Equality & Identity ................................................................................................................................. 71
Section 35.4: IF, TRY and others are expressions, not statements ......................................................................... 72
Chapter 36: Java 8 Stream Equivalents ......................................................................................................... 73
Section 36.1: Accumulate names in a List ................................................................................................................. 73
Section 36.2: Collect example #5 - find people of legal age, output formatted string ........................................ 73
Section 36.3: Collect example #6 - group people by age, print age and names together ................................. 73
Section 36.4: Dierent Kinds of Streams #7 - lazily iterate Doubles, map to Int, map to String, print each
................................................................................................................................................................................ 74
Section 36.5: Counting items in a list after filter is applied ..................................................................................... 75
Section 36.6: Convert elements to strings and concatenate them, separated by commas ............................... 75
Section 36.7: Compute sum of salaries of employee .............................................................................................. 75
Section 36.8: Group employees by department ...................................................................................................... 75
Section 36.9: Compute sum of salaries by department .......................................................................................... 75
Section 36.10: Partition students into passing and failing ....................................................................................... 75
Section 36.11: Names of male members ................................................................................................................... 76
Section 36.12: Group names of members in roster by gender ............................................................................... 76
Section 36.13: Filter a list to another list .................................................................................................................... 76
Section 36.14: Finding shortest string a list ............................................................................................................... 76
Section 36.15: Dierent Kinds of Streams #2 - lazily using first item if exists ....................................................... 76
Section 36.16: Dierent Kinds of Streams #3 - iterate a range of Integers .......................................................... 77
Section 36.17: Dierent Kinds of Streams #4 - iterate an array, map the values, calculate the average
................................................................................................................................................................................ 77
Section 36.18: Dierent Kinds of Streams #5 - lazily iterate a list of strings, map the values, convert to Int,
find max ............................................................................................................................................................... 77
Section 36.19: Dierent Kinds of Streams #6 - lazily iterate a stream of Ints, map the values, print results
................................................................................................................................................................................ 77
Section 36.20: How streams work - filter, upper case, then sort a list ................................................................... 78
Section 36.21: Dierent Kinds of Streams #1 - eager using first item if it exists ................................................... 78
Section 36.22: Collect example #7a - Map names, join together with delimiter ................................................... 78
Section 36.23: Collect example #7b - Collect with SummarizingInt ....................................................................... 79
Chapter 37: Kotlin Caveats .................................................................................................................................... 81
Section 37.1: Calling a toString() on a nullable type ................................................................................................ 81
LearnLoner.com
LearnLoner
Appendix A: Configuring Kotlin build ................................................................................................................ 82
Section A.1: Gradle configuration ............................................................................................................................... 82
Section A.2: Using Android Studio ............................................................................................................................. 83
Section A.3: Migrating from Gradle using Groovy script to Kotlin script ............................................................... 84
Credits .............................................................................................................................................................................. 86
You may also like ........................................................................................................................................................ 88
LearnLoner.com
LearnLoner
Chapter 1: Getting started with Kotlin
Version Release Date
1.0.0 2016-02-15
1.0.1 2016-03-16
1.0.2 2016-05-13
1.0.3 2016-06-30
1.0.4 2016-09-22
1.0.5 2016-11-08
1.0.6 2016-12-27
1.1.0 2017-03-01
1.1.1 2017-03-14
1.1.2 2017-04-25
1.1.3 2017-06-23
1.1.6 2017-11-13
1.2.2 2018-01-17
1.2.3 2018-03-01
1.2.4 2018-04-19
package my.program
Place the above code into a file named Main.kt (this filename is entirely arbitrary)
When targeting the JVM, the function will be compiled as a static method in a class with a name derived from the
filename. In the above example, the main class to run would be my.program.MainKt.
To change the name of the class that contains top-level functions for a particular file, place the following annotation
at the top of the file above the package statement:
@file:JvmName("MyApp")
See also:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 2
package my.program
class App {
companion object {
@JvmStatic fun main(args: Array<String>) {
println("Hello World")
}
}
}
The class name that you will run is the name of your class, in this case is my.program.App.
The advantage to this method over a top-level function is that the class name to run is more self-evident, and any
other functions you add are scoped into the class App. This is similar to the Object Declaration example, other
than you are in control of instantiating any classes to do further work.
class App {
companion object {
@JvmStatic fun main(args: Array<String>) {
App().run()
}
}
fun run() {
println("Hello World")
}
}
See also:
package my.program
object App {
@JvmStatic fun main(args: Array<String>) {
println("Hello World")
}
}
The class name that you will run is the name of your object, in this case is my.program.App.
The advantage to this method over a top-level function is that the class name to run is more self-evident, and any
other functions you add are scoped into the class App. You then also have a singleton instance of App to store state
and do other work.
See also:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 3
Section 1.4: Main methods using varargs
All of these main method styles can also be used with varargs:
package my.program
return max;
Here, Enter two number from the command line to find the maximum number. Output:
The value of b is 89
Max number is: 89
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 4
For !! Operator Please check Null Safety.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 5
Chapter 2: Basics of Kotlin
This topic covers the basics of Kotlin for beginners.
2. Single-Expression functions:When a function returns a single expression, the curly braces can be omitted and the
body is specified after = symbol
Explicitly declaring the return type is optional when this can be inferred by the compiler
In java:
int num=10
String s = "i =" + i;
In Kotlin
val num = 10
val s = "i = $num"
4. In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those
that can not (non-null references). For example, a regular variable of type String can not hold null:
5. In Kotlin,== actually checks for equality of values. By convention, an expression like a == b is translated to
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 6
Chapter 3: Strings
Section 3.1: String Equality
In Kotlin strings are compared with == operator which check for their structural equality.
Escaped string
Raw string
Escaped string handles special characters by escaping them. Escaping is done with a backslash. The following
escape sequences are supported: \t, \b, \n, \r, \', \", \\ and \$. To encode any other character, use the Unicode
escape sequence syntax: \uFF00.
Raw string delimited by a triple quote """, contains no escaping and can contain newlines and any other
characters
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 7
Default margin prefix is pipe character |, this can be set as a parameter to trimMargin; e.g. trimMargin(">").
for (c in str) {
println(c)
}
val i = 10
val s = "i = $i" // evaluates to "i = 10"
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
The exception is raw strings, which do not support escaping. In raw strings you can use the following syntax to
represent a dollar sign.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 8
Chapter 4: Arrays
Section 4.1: Generic Arrays
Generic arrays in Kotlin are represented by Array<T>.
To create an array with given size and initial values, use the constructor:
strings.set(2, "ChangedItem")
print(strings.get(2)) // prints "ChangedItem"
The returned array will always have a nullable type. Arrays of non-nullable items can't be created uninitialized.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 9
Section 4.6: Extensions
average() is defined for Byte, Int, Long, Short, Double, Float and always returns Double:
getOrNull(index: Int) returns null if index is out of bounds, otherwise an item of the array
first(), last()
sortedArray(), sortedArrayDescending() creates and returns a new array with sorted elements of current
min(), max()
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 10
Chapter 5: Collections
Unlike many languages, Kotlin distinguishes between mutable and immutable collections (lists, sets, maps, etc).
Precise control over exactly when collections can be edited is useful for eliminating bugs, and for designing good
APIs.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 11
Chapter 6: Enum
Section 6.1: Initialization
Enum classes as any other classes can have a constructor and be initialized
Each enum constant is an object. Enum constants are separated with commas.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 12
println(Planet.MARS) // MARS[population=0]
Planet.MARS.population = 3
println(Planet.MARS) // MARS[population=3]
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 13
Chapter 7: Functions
Parameter Details
Name Name of the function
Params Values given to the function with a name and type: Name:Type
Type Return type of the function
Type Argument Type parameter used in generic programming (not necessarily return type)
ArgName Name of value given to the function
ArgType Type specifier for ArgName
ArgNames List of ArgName separated by commas
Functions without a receiver will be converted to (ParamTypeA, ParamTypeB, ...) -> ReturnType where
ParamTypeA, ParamTypeB ... are the type of the function parameters and `ReturnType1 is the type of function return
value.
Functions with a receiver (be it an extension function or a member function) has a different syntax. You have to add
the type name of the receiver before the double colon:
class Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function4<Foo, Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo, Foo0, Foo1, Foo2) -> Bar
// takes 4 parameters, with receiver as first and actual parameters following, in their order
class Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
However, when a function's receiver is an object, the receiver is omitted from parameter list, because these is and
only is one instance of such type.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 14
object Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
// takes 3 parameters, receiver not needed
object Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
Since kotlin 1.1, function reference can also be bounded to a variable, which is then called a bounded function
reference.
Version ≥ 1.1.0
fun makeList(last: String?): List<String> {
val list = mutableListOf("a", "b", "c")
last?.let(list::add)
return list
}
Note this example is given only to show how bounded function reference works. It's bad practice in all other
senses.
There is a special case, though. An extension function declared as a member can't be referenced.
class Foo
class Bar {
fun Foo.foo() {}
val ref = Foo::foo // compile error
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 15
Section 7.3: Inline Functions
Functions can be declared inline using the inline prefix, and in this case they act like macros in C - rather than
being called, they are replaced by the function's body code at compile time. This can lead to performance benefits
in some circumstances, mainly where lambdas are used as function parameters.
One difference from C macros is that inline functions can't access the scope from which they're called:
fun main() {
val name = "Foo"
sayMyName() # => Unresolved reference: name
}
The last statement inside a lambda function is automatically the return value.
The type's are optional, if you put the lambda on a place where the compiler can infer the types.
Multiple arguments:
If the lambda function only needs one argument, then the argument list can be omitted and the single argument be
referred to using it instead.
If the only argument to a function is a lambda function, then parentheses can be completely omitted from the
function call.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 16
the operator modifier:
For example, you could use the vaguest type, () -> Any?, to declare a function which executes a lambda function
twice:
fun main() {
twice {
println("Foo")
} # => Foo
# => Foo
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 17
Chapter 8: Vararg Parameters in Functions
Section 8.1: Basics: Using the vararg keyword
Define the function using the vararg keyword.
Now you can pass as many parameters (of the correct type) into the function as you want.
Notes: Vararg parameters must be the last parameter in the parameter list.
The spread operator can also be used in the middle of the parameters...
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 18
Chapter 9: Conditional Statements
Section 9.1: When-statement argument matching
When given an argument, the when-statement matches the argument against the branches in sequence. The
matching is done using the == operator which performs null checks and compares the operands using the equals
function. The first matching one will be executed.
when (x) {
"English" -> print("How are you?")
"German" -> print("Wie geht es dir?")
else -> print("I don't know that language yet :(")
}
The when statement also knows some more advanced matching options:
To be used as an expression, the when-statement must be exhaustive, i.e. either have an else branch or cover all
possibilities with the branches in another way.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 19
val str = if (condition) "Condition met!" else "Condition not met!"
Note that the else-branch is not optional if the if-statement is used as an expression.
This can also been done with a multi-line variant with curly brackets and multiple else if statements.
TIP: Kotlin can infer the type of the variable for you but if you want to be sure of the type just annotate it
on the variable like: val str: String = this will enforce the type and will make it easier to read.
when {
str.length == 0 -> print("The string is empty!")
str.length > 5 -> print("The string is short!")
else -> print("The string is long!")
}
if (str.length == 0) {
print("The string is empty!")
} else if (str.length > 5) {
print("The string is short!")
} else {
print("The string is long!")
}
Just like with the if-statement, the else-branch is optional, and you can add as many or as few branches as you like.
You can also have multiline-branches:
when {
condition -> {
doSomething()
doSomeMore()
}
else -> doSomethingElse()
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 20
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
As you can see in second case line (Monday and Tuesday) it is also possible to combine two or more enum values.
If your cases are not exhaustive the compile will show an error. You can use else to handle default cases:
Though the same can be done using if-then-else construct, when takes care of missing enum values and makes it
more natural.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 21
Chapter 10: Loops in Kotlin
Section 10.1: Looping over iterables
You can loop over any iterable by using the standard for-loop:
for(i in 0..9) {
print(i)
}
There is also a functional approach to iterating included in the standard library, without apparent language
constructs, using the forEach function:
iterable.forEach {
print(it.toString())
}
it in this example implicitly holds the current element, see Lambda Functions
while(true) {
if(condition1) {
continue // Will immediately start the next iteration, without executing the rest of the
loop body
}
if(condition2) {
break // Will exit the loop completely
}
}
If you have nested loops, you can label the loop statements and qualify the break and continue statements to
specify which loop you want to continue or break:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 22
outer@ for(i in 0..10) {
inner@ for(j in 0..10) {
break // Will break the inner loop
break@inner // Will break the inner loop
break@outer // Will break the outer loop
}
}
This approach won't work for the functional forEach construct, though.
println(factorial(10)) // 3628800
In the example above, the factorial function will be called repeatedly by itself until the given condition is met.
while(condition) {
doSomething()
}
do {
doSomething()
} while (condition)
In the do-while loop, the condition block has access to values and variables declared in the loop body.
For example, the map function can be used to transform a list of items.
One of the many advantages of this style is it allows to chain operations in a similar fashion. Only a minor
modification would be required if say, the list above were needed to be filtered for even numbers. The filter
function can be used.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 23
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
val numberStrings = numbers.filter { it % 2 == 0 }.map { "Number $it" }
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 24
Chapter 11: Ranges
Range expressions are formed with rangeTo functions that have the operator form .. which is complemented by in
and !in. Range is defined for any comparable type, but for integral primitive types it has an optimized
implementation
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 25
Chapter 12: Regex
Section 12.1: Idioms for Regex Matching in When Expression
Using immutable locals:
Uses less horizontal space but more vertical space than the "anonymous temporaries" template. Preferable over
the "anonymous temporaries" template if the when expression is in a loop--in that case, regex definitions should be
placed outside the loop.
import kotlin.text.regex
when {
regex1.matches(string) -> /* do stuff */
regex2.matches(string) -> /* do stuff */
/* etc */
}
Uses less vertical space but more horizontal space than the "immutable locals" template. Should not be used if then
when expression is in a loop.
import kotlin.text.regex
when {
Regex( /* pattern */ ).matches(string) -> /* do stuff */
Regex( /* pattern */ ).matches(string) -> /* do stuff */
/* etc */
}
Has the benefit of closely emulating the "argument-ful" when syntax. This is beneficial because it more clearly
indicates the argument of the when expression, and also precludes certain programmer mistakes that could arise
from having to repeat the when argument in every whenEntry. Either the "immutable locals" or the "anonymous
temporaries" template may be used with this implementation the visitor pattern.
import kotlin.text.regex
when (RegexWhenArgument(string)) {
Regex( /* pattern */ ) -> /* do stuff */
Regex( /* pattern */ ) -> /* do stuff */
/* etc */
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 26
And the minimal definition of the wrapper class for the when expression argument:
To work with regular expressions in Kotlin, you need to use the Regex(pattern: String) class and invoke
functions like find(..) or replace(..) on that regex object.
An example on how to use the Regex class that returns true if the input string contains c or d:
The essential thing to understand with all the Regex functions is that the result is based on matching the regex
pattern and the input string. Some of the functions requires a full match, while the rest requires only a partial
match. The containsMatchIn(..) function used in the example requires a partial match and is explained later in
this post.
Both find(..) and matchEntire(..) will return a MatchResult? object. The ? character after MatchResult is
necessary for Kotlin to handle null safely.
An example that demonstrates how Kotlin handles null safely from a Regex function, when the find(..) function
returns null:
val matchResult =
Regex("c|d").find("efg") // matchResult: null
val a = matchResult?.value // a: null
val b = matchResult?.value.orEmpty() // b: ""
a?.toUpperCase() // Still needs question mark. => null
b.toUpperCase() // Accesses the function directly. => ""
With the orEmpty() function, b can't be null and the ? character is unnecessary when you call functions on b.
If you don't care about this safe handling of null values, Kotlin allows you to work with null values like in Java with
the !! characters:
Kotlin provides an improvement over Java with a raw string that makes it possible to write pure regex patterns
without double backslashes, that are necessary with a Java string. A raw string is represented with a triple quote:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 27
find(input: CharSequence, startIndex: Int): MatchResult?
The input string will be matched against the pattern in the Regex object. It returns a Matchresult? object with the
first matched text after the startIndex, or null if the pattern didn't match the input string. The result string is
retrieved from the MatchResult? object's value property. The startIndex parameter is optional with the default
value 0.
To extract the first valid phone number from a string with contact details:
With no valid phone number in the input string, the variable phoneNumber will be null.
Returns all the matches from the input string that matches the regex pattern.
To print out all numbers separated with space, from a text with letters and digits:
println(result) // => 12 34
The matchedResults variable is a sequence with MatchResult objects. With an input string without digits, the
findAll(..) function will return an empty sequence.
If all the characters in the input string matches the regex pattern, a string equal to the input will be returned. Else,
null will be returned.
Returns true if the whole input string matches the regex pattern. False otherwise.
Returns true if part of the input string matches the regex pattern. False otherwise.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 28
Regex("""\d+""").containsMatchIn("Fifty dollars") // => false
There is one element in the list for each split. The first input string has three numbers. That results in a list with
three elements.
Replaces all matches of the regex pattern in the input string with the replacement string.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 29
Chapter 13: Basic Lambdas
Section 13.1: Lambda as parameter to filter function
val allowedUsers = users.filter { it.age > MINIMUM_AGE }
object Benchmark {
fun realtime(body: () -> Unit): Duration {
val start = Instant.now()
try {
body()
} finally {
val end = Instant.now()
return Duration.between(start, end)
}
}
}
Usage:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 30
Chapter 14: Null Safety
Section 14.1: Smart casts
If the compiler can infer that an object can't be null at a certain point, you don't have to use the special operators
anymore:
Note: The compiler won't allow you to smart cast mutable variables that could potentially be modified
between the null-check and the intended usage.
If a variable is accessible from outside the scope of the current block (because they are members of a
non-local object, for example), you need to create a new, local reference which you can then smart cast
and use.
For instance:
The expression above returns "Nothing here" if data?.first() or data itself yield a null value else the result of
data?.first().
It is also possible to throw exceptions using the same syntax to abort code execution.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 31
val value: String = data?.second()
?: throw IllegalArgumentException("Value can't be null!")
Reminder: NullPointerExceptions can be thrown using the assertion operator (e.g. data!!.second()!!)
var string : String = "Hello World!" var nullableString: String? = null string = nullableString // Compiler error: Can't
assign nullable to non-nullable type. nullableString = string // This will work however!
Now, a can be null. So when we need to access value of a, then we need to perform safety check, whether it
contains value or not. We can perform this safety check by conventional if...else statement.
But here comes advance operator Elvis(Operator Elvis : ?:). Above if...else can be expressed with the Elvis
operator as below:
val b = a?.length ?: -1
If the expression to the left of ?: (here : a?.length) is not null, the elvis operator returns it, otherwise it returns the
expression to the right (here: -1). Right-hand side expression is evaluated only if the left-hand side is null.
The first one, ?., gives you the property or function you're trying to access, or it gives you null if the object is null:
An elegant way to call multiple methods of a null-checked object is using Kotlin's apply like this:
obj?.apply {
foo()
bar()
}
This will call foo and bar on obj (which is this in the apply block) only if obj is non-null, skipping the entire block
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 32
otherwise.
To bring a nullable variable into scope as a non-nullable reference without making it the implicit receiver of function
and property calls, you can use let instead of apply:
notnull could be named anything, or even left out and used through the implicit lambda parameter it.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 33
Chapter 15: Class Delegation
A Kotlin class may implement an interface by delegating its methods and properties to another object that
implements that interface. This provides a way to compose behavior using association rather than inheritance.
class Bar {
fun example() {
println("Hello, world!")
}
}
Baz(Bar()).example()
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 34
Chapter 16: Class Inheritance
Parameter Details
Base Class Class that is inherited from
Derived Class Class that inherits from Base Class
Init Arguments Arguments passed to constructor of Base Class
Function Definition Function in Derived Class that has different code than the same in the Base Class
DC-Object ”Derived Class-Object“ Object that has the type of the Derived Class
Any object-oriented programming language has some form of class inheritance. Let me revise:
Imagine you had to program a bunch of fruit: Apples, Oranges and Pears. They all differ in size, shape and color,
that's why we have different classes.
But let's say their differences don't matter for a second and you just want a Fruit, no matter which exactly? What
return type would getFruit() have?
The answer is class Fruit. We create a new class and make all fruits inherit from it!
Note: abstract classes, sealed classes and interfaces will be open by default.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 35
Section 16.3: Inheriting methods from a class
Defining the base class:
open class Person {
fun jump() {
println("Jumping...")
}
}
Overriding methods:
interface Ship {
fun sail()
fun sink()
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 36
canSail = false
}
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 37
Chapter 17: Visibility Modifiers
In Kotlin, there are 4 types of visibility modifiers are available.
Protected: This can only be accessed from the class defining it and any derived classes.
Internal: This can only be accessed from the scope of the class defining it.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 38
Chapter 18: Generics
Parameter Details
TypeName Type Name of generic parameter
UpperBound Covariant Type
LowerBound Contravariant Type
ClassName Name of the class
A List can hold numbers, words or really anything. That's why we call the List generic.
Generics are basically used to define which types a class can hold and which type an object currently holds.
Widespread examples of declaration-site variance are List<out T>, which is immutable so that T only appears as
the return value type, and Comparator<in T>, which only receives T as argument.
Out-projection:
In-projection:
putList[0] // This expression has type Any, since no upper bound is specified
Star-projection
starList[0] // This expression has type Any, since no upper bound is specified
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 39
starList.add(someValue) // Error, lower bound for generic is not specified
See also:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 40
Chapter 19: Interfaces
Section 19.1: Interface with default implementations
An interface in Kotlin can have default implementations for functions:
interface MyInterface {
fun withImplementation() {
print("withImplementation() was called")
}
}
Classes implementing such interfaces will be able to use those functions without reimplementing
Properties
interface MyInterface2 {
val helloWorld
get() = "Hello World!"
}
interface MyInterface3 {
// this property won't compile!
var helloWorld: Int
get() = field
set(value) { field = value }
}
Multiple implementations
When multiple interfaces implement the same function, or all of them define with one or more implementing, the
derived class needs to manually resolve proper call
interface A {
fun notImplemented()
fun implementedOnlyInA() { print("only A") }
fun implementedInBoth() { print("both, A") }
fun implementedInOne() { print("implemented in A") }
}
interface B {
fun implementedInBoth() { print("both, B") }
fun implementedInOne() // only defined
}
class MyClass: A, B {
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 41
override fun notImplemented() { print("Normal implementation") }
interface MyInterface {
val property: Int // abstract
fun foo() {
print(property)
}
}
If the method in the interface has its own default implementation, we can use super keyword to access it.
super.funcOne()
interface MyInterface {
fun bar()
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 42
}
interface FirstTrait {
fun foo() { print("first") }
fun bar()
}
interface SecondTrait {
fun foo() { print("second") }
fun bar() { print("bar") }
}
// function bar() only has a default implementation in one interface and therefore is ok.
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 43
Chapter 20: Singleton objects
An object is a special kind of class, which can be declared using object keyword. Objects are similar to Singletons (a
design pattern) in java. It also functions as the static part of java. Beginners who are switching from java to kotlin
can vastly use this feature, in place of static, or singletons.
From any other class, just invoke the variable and functions in this way:
CommonUtils.anyname
CommonUtils.dispMsg("like static call")
object SharedRegistry {
fun register(key: String, thing: Object) {}
}
result
Hello,
World!
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 45
Chapter 22: Annotations
Section 22.1: Meta-annotations
When declaring an annotation, meta-info can be included using the following meta-annotations:
@Target: specifies the possible kinds of elements which can be annotated with the annotation (classes,
functions, properties, expressions etc.)
@Retention specifies whether the annotation is stored in the compiled class files and whether it's visible
through reflection at runtime (by default, both are true.)
@Repeatable allows using the same annotation on a single element multiple times.
@MustBeDocumented specifies that the annotation is part of the public API and should be included in the class
or method signature shown in the generated API documentation.
Example:
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Fancy
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 46
Chapter 23: Type aliases
With type aliases, we can give an alias to other type. It's ideal for giving a name to function types like (String) ->
Boolean or generic type like Pair<Person, Person>.
Type aliases support generics. An alias can replace a type with generics and an alias can be generics.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 47
Chapter 24: Type-Safe Builders
Section 24.1: Type-safe tree structure builder
Builders can be defined as a set of extension functions taking lambda expressions with receivers as arguments. In
this example, a menu of a JFrame is being built:
import javax.swing.*
These functions can then be used to build a tree structure of objects in an easy way:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 48
Chapter 25: Delegated properties
Kotlin can delegate the implementation of a property to a handler object. Some standard handlers are included,
such as lazy initialization or observable properties. Custom handlers can also be created.
So let's say we have to save some sort of reference and we wanted to avoid memory leaks, here is where
WeakReference comes in.
class MyMemoryExpensiveClass {
companion object {
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 49
var reference: WeakReference<MyMemoryExpensiveClass>? = null
init {
reference = WeakReference(this)
}
}
Now this is just with one WeakReference. To Reduce this boilerplate, we can use a custom property delegate to help
us like so:
So Now we can use variables that are wrapped with WeakReference just like normal nullable variables !
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()
init {
reference = this
}
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 50
Chapter 26: Reflection
Reflection is a language's ability to inspect code at runtime instead of compile time.
val c1 = String::class
val c2 = MyClass::class
The latter example will be optimized by the compiler to not allocate an intermediate KClass instance.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 51
}
Running this code will cause an exception to be thrown. Property private val privateField is declared private
and calling member.get(example) on it will not succeed. One way to handle this it to filter out private properties. To
do that we have to check the visibility modifier of a property's Java getter. In case of private val the getter does
not exist so we can assume private access.
The helper function and it's usage might look like this:
class TestClass {
val readOnlyProperty: String
get() = "Read only!"
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 52
}
}
Getting mutable properties builds on getting all properties, filtering mutable properties by type. We also need to
check visibility, as reading private properties results in run time exception.
To set all String properties to "Our Value" we can additionally filter by the return type. Since Kotlin is based on
Java VM, Type Erasure is in effect, and thus Properties returning generic types such as List<String> will be the
same as List<Any>. Sadly reflection is not a golden bullet and there is no sensible way to avoid this, so you need to
watch out in your use-cases.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 53
Chapter 27: Extension Methods
Section 27.1: Potential Pitfall: Extensions are Resolved
Statically
The extension method to be called is determined at compile-time based on the reference-type of the variable being
accessed. It doesn't matter what the variable's type is at runtime, the same extension method will always be called.
callMyExtension(Sub())
The above example will print "Defined for Super", because the declared type of the variable myVar is Super.
Above an extension method is defined for the type IntArray. Note that the object for which the extension method
is defined (called the receiver) is accessed using the keyword this.
In the example, the extension property is color. It uses an explicit colorCache which can be used with this as no
lazy is necessary:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 54
val KColor.color: Color
get() = colorCache.getOrPut(this) { Color(value, true) }
println(1999549L.humanReadable())
println(someInt.humanReadable())
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 55
val x: Path = Paths.get("dirName").apply {
if (Files.notExists(this)) throw IllegalStateException("The important file does not exist")
}
But the use of apply is not that clear as to your intent. Sometimes it is clearer to create a similar extension function
to in effect rename the action and make it more self-evident. This should not be allowed to get out of hand, but for
very common actions such as verification:
Which now let's people know what to expect within the lambda parameter.
Note that the type parameter T for verifiedBy is same as T: Any? meaning that even nullable types will be able to
use that version of the extension. Although verifiedWith requires non-nullable.
class Something {
companion object {}
}
class SomethingElse {
}
SomethingElse.fromString("") //invalid
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 56
Section 27.9: Extensions for easier reference View from code
You can use extensions for reference View, no more boilerplate after you created the views.
Extensions
inline fun <reified T : View> View.find(id: Int): T = findViewById(id) as T
inline fun <reified T : View> Activity.find(id: Int): T = findViewById(id) as T
inline fun <reified T : View> Fragment.find(id: Int): T = view?.findViewById(id) as T
inline fun <reified T : View> RecyclerView.ViewHolder.find(id: Int): T = itemView?.findViewById(id)
as T
Usage
val yourButton by lazy { find<Button>(R.id.yourButtonId) }
val yourText by lazy { find<TextView>(R.id.yourTextId) }
val yourEdittextOptional by lazy { findOptional<EditText>(R.id.yourOptionEdittextId) }
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 57
Chapter 28: DSL Building
Focus on the syntax details to design internal DSLs in Kotlin.
@Test
fun test() {
100.plusOne() shouldBe 101
}
val r = Random(233)
infix inline operator fun Int.rem(block: () -> Unit) {
if (r.nextInt(100) < this) block()
}
you can write the following DSL-like code in your production code:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 58
operator fun <R> String.invoke(block: () -> R) = {
try { block.invoke() }
catch (e: AssertException) { System.err.println("$this\n${e.message}") }
}
If you feel confused with shouldBe above, see the example Infix approach to build DSL.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 59
Chapter 29: Idioms
Section 29.1: Serializable and serialVersionUid in Kotlin
To create the serialVersionUID for a class in Kotlin you have a few options all involving adding a member to the
companion object of the class.
The most concise bytecode comes from a private const val which will become a private static variable on the
containing class, in this case MySpecialCase:
You can also use these forms, each with a side effect of having getter/setter methods which are not necessary
for serialization...
This creates the static field but also creates a getter as well getSerialVersionUID on the companion object which is
unnecessary.
This creates the static field but also creates a static getter as well getSerialVersionUID on the containing class
MySpecialCase which is unnecessary.
class MyTable private constructor(table: Table<Int, Int, Int>) : Table<Int, Int, Int> by table {
With this, you can just call the constructor of MyTable like that: MyTable(). The Table<Int, Int, Int> to which
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 60
MyTable delegates will be created privately. Constructor caller knows nothing about it.
The difference between let and also is that you can return any value from a let block. also in the other hand will always
return Unit.
Now why this is useful, you ask? Because if you call a method which can return null and you want to run some
code only when that return value is not null you can use let or also like this:
This piece of code will only run the let block when str is not null. Note the null safety operator (?).
calls the specified function block with this value as its receiver and returns this value.
While the kdoc is not so helpful apply is indeed an useful function. In layman's terms apply establishes a scope in
which this is bound to the object you called apply on. This enables you to spare some code when you need to call
multiple methods on an object which you will then return later. Example:
File(dir).apply { mkdirs() }
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 61
fun doSomething() {
someOtherAction()
return this
}
But you can also make them more functional by creating an extension function such as:
fun doSomething() {
return fluently { someOtherAction() }
}
data class User(var firstname: String, var lastname: String, var age: Int)
The code above creates a User class with the following automatically generated:
Getters and Setters for all properties (getters only for vals)
equals()
hashcode()
toString()
copy()
componentN() (where N is the corresponding property in order of declaration)
data class User(var firstname: String = "Joe", var lastname: String = "Bloggs", var age: Int = 20)
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 62
Chapter 30: RecyclerView in Kotlin
I just want to share my little bit knowledge and code of RecyclerView using Kotlin.
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = LinearLayoutManager(this)
mAdapter.RecyclerAdapter(getList(), this)
mRecyclerView.adapter = mAdapter
}
this one is your recycler view adapter class and create main_item.xml file what you want
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 64
Chapter 31: logging in kotlin
Section 31.1: kotlin.logging
class FooWithLogging {
companion object: KLogging()
fun bar() {
logger.info { "hello $name" }
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 65
Chapter 32: Exceptions
Section 32.1: Catching exception with try-catch-finally
Catching exceptions in Kotlin looks very similar to Java
try {
doSomething()
}
catch(e: MyException) {
handle(e)
}
finally {
cleanup()
}
try {
doSomething()
}
catch(e: FileSystemException) {
handle(e)
}
catch(e: NetworkException) {
handle(e)
}
catch(e: MemoryException) {
handle(e)
}
finally {
cleanup()
}
Kotlin doesn't have checked exceptions, so you don't have to catch any exceptions.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 66
Chapter 33: JUnit
Section 33.1: Rules
To add a JUnit rule to a test fixture:
The @JvmField annotation is necessary to expose the backing field with the same visibility (public) as the myRule
property (see answer). JUnit rules require the annotated rule field to be public.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 67
Chapter 34: Kotlin Android Extensions
Kotlin has a built-in view injection for Android, allowing to skip manual binding or need for frameworks such as
ButterKnife. Some of the advantages are a nicer syntax, better static typing and thus being less error-prone.
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My button"/>
</LinearLayout>
We can use Kotlin extensions to call the button without any additional binding like so:
import kotlinx.android.synthetic.main.activity_main.my_button
You can also import all ids appearing in layout with a * notation
Synthetic views can't be used outside of Activities/Fragments/Views with that layout inflated:
import kotlinx.android.synthetic.main.activity_main.my_button
class NotAView {
init {
// This sample won't compile!
my_button.setText("Kotlin rocks!")
}
}
In your project-local (not top-level) build.gradle append extensions plugin declaration below your Kotlin plugin,
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 68
on top-level indentation level.
buildscript {
...
}
Section 34.3: Painful listener for getting notice, when the view
is completely drawn now is so simple and awesome with
Kotlin's extension
mView.afterMeasured {
// inside this block the view is completely drawn
// you can get view's height/width, it.height / it.width
}
android {
productFlavors {
paid {
...
}
free {
...
}
}
}
And for example, only the free flavor has a buy button:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 69
<Button
android:id="@+id/buy_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Buy full version"/>
</LinearLayout>
import kotlinx.android.synthetic.free.main_activity.buy_button
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 70
Chapter 35: Kotlin for Java Developers
Most people coming to Kotlin do have a programming background in Java.
This topic collects examples comparing Java to Kotlin, highlighting the most important differences and those gems
Kotlin offers over Java.
val i : Int = 42
They start with either val or var, making the declaration final ("value") or variable.
Thanks to Kotlin's type inference the explicit type declaration can be omitted if there is an assignment with a
type the compiler is able to unambiguously detect
Java Kotlin
int i = 42; var i = 42 (or var i : Int = 42)
final int i = 42; val i = 42
Java Kotlin
a.equals(b); a == b
a == b; a === b
a != b; a !== b
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 71
See: https://kotlinlang.org/docs/reference/equality.html
So, for example, Kotlin does not have Java's ternary Elvis Operator, but you can write something like this:
val i = try {
Integer.parseInt(someString)
}
catch (ex : Exception)
{
42
}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 72
Chapter 36: Java 8 Stream Equivalents
Kotlin provides many extension methods on collections and iterables for applying functional-style operations. A
dedicated Sequence type allows for lazy composition of several such operations.
// Kotlin:
val list = people.map { it.name } // toList() not needed
System.out.println(phrase);
// In Germany Max and Peter and Pamela are of legal age.
// Kotlin:
val phrase = persons
.filter { it.age >= 18 }
.map { it.name }
.joinToString(" and ", "In Germany ", " are of legal age.")
println(phrase)
// In Germany Max and Peter and Pamela are of legal age.
And as a side note, in Kotlin we can create simple data classes and instantiate the test data as follows:
// Kotlin:
// data class has equals, hashcode, toString, and copy methods automagically
data class Person(val name: String, val age: Int)
System.out.println(map);
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 73
// {18=Max, 23=Peter;Pamela, 12=David}
Ok, a more interest case here for Kotlin. First the wrong answers to explore variations of creating a Map from a
collection/sequence:
// Kotlin:
val map1 = persons.map { it.age to it.name }.toMap()
println(map1)
// output: {18=Max, 23=Pamela, 12=David}
// Result: duplicates overridden, no exception similar to Java 8
// Kotlin:
val map6 = persons.groupBy { it.age }.mapValues { it.value.joinToString(";") { it.name } }
println(map6)
// output: {18=Max, 23=Peter;Pamela, 12=David}
// Result: YAY!!
We just needed to join the matching values to collapse the lists and provide a transformer to joinToString to move
from Person instance to the Person.name.
// a1
// a2
// a3
// Kotlin:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 74
sequenceOf(1.0, 2.0, 3.0).map(Double::toInt).map { "a$it" }.forEach(::println)
// Kotlin:
val count = items.filter { it.startsWith('t') }.size
// but better to not filter, but count with a predicate
val count = items.count { it.startsWith('t') }
// Kotlin:
val joined = things.joinToString() // ", " is used as separator, by default
// Kotlin:
val total = employees.sumBy { it.salary }
// Kotlin:
val byDept = employees.groupBy { it.department }
// Kotlin:
val totalByDept = employees.groupBy { it.dept }.mapValues { it.value.sumBy { it.salary }}
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 75
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
// Kotlin:
val passingFailing = students.partition { it.grade >= PASS_THRESHOLD }
// Kotlin:
val namesOfMaleMembers = roster.filter { it.gender == Person.Sex.MALE }.map { it.name }
// Kotlin:
val namesByGender = roster.groupBy { it.gender }.mapValues { it.value.map { it.name } }
// Kotlin:
val filtered = items.filter { item.startsWith('o') }
// Kotlin:
val shortest = items.minBy { it.length }
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 76
.ifPresent(System.out::println);
// Kotlin:
sequenceOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
// Kotlin:
arrayOf(1,2,3).map { 2 * it + 1}.average().apply(::println)
// Kotlin:
sequenceOf("a1", "a2", "a3")
.map { it.substring(1) }
.map(String::toInt)
.max().apply(::println)
// a1
// a2
// a3
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 77
Section 36.20: How streams work - filter, upper case, then
sort a list
// Java:
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
// C1
// C2
// Kotlin:
val list = listOf("a1", "a2", "b1", "c2", "c1")
list.filter { it.startsWith('c') }.map (String::toUpperCase).sorted()
.forEach (::println)
// Kotlin:
listOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
// Kotlin:
inline fun String?.ifPresent(thenDo: (String)->Unit) = this?.apply { thenDo(this) }
// Java (concise)
String names = persons.stream().map(p -> p.name.toUpperCase()).collect(Collectors.joining(" | "));
// Kotlin:
val names = persons.map { it.name.toUpperCase() }.joinToString(" | ")
System.out.println(ageSummary);
// IntSummaryStatistics{count=4, sum=76, min=12, average=19.000000, max=23}
// Kotlin:
println(stats)
// output: SummaryStatisticsInt(count=4, sum=76, min=12, max=23, avg=19.0)
But it is better to create an extension function, 2 actually to match styles in Kotlin stdlib:
// Kotlin:
inline fun Collection<Int>.summarizingInt(): SummaryStatisticsInt
= this.fold(SummaryStatisticsInt()) { stats, num -> stats.accumulate(num) }
Now you have two ways to use the new summarizingInt functions:
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 79
// or
And all of these produce the same results. We can also create this extension to work on Sequence and for
appropriate primitive types.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 80
Chapter 37: Kotlin Caveats
Section 37.1: Calling a toString() on a nullable type
A thing to look out for when using the toString method in Kotlin is the handling of null in combination with the
String?.
// Incorrect:
val text = view.textField?.text.toString() ?: ""
You would expect that if the field did not exists the value would be empty string but in this case it is "null".
// Correct:
val text = view.textField?.text?.toString() ?: ""
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 81
Appendix A: Configuring Kotlin build
Section A.1: Gradle configuration
kotlin-gradle-plugin is used to compile Kotlin code with Gradle. Basically, its version should correspond to the
Kotlin version you want to use. E.g. if you want to use Kotlin 1.0.3, then you need to apply kotlin-gradle-plugin
version 1.0.3 too.
buildscript {
ext.kotlin_version = '1.0.3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Then you need to apply this plugin to your project. The way you do this differs when targeting different platforms:
Targeting JVM
apply plugin: 'kotlin'
Targeting Android
apply plugin: 'kotlin-android'
Targeting JS
apply plugin: 'kotlin2js'
You may need to configure SourceSets if you're using custom project layout.
Finally, you'll need to add Kotlin standard library dependency to your project:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
If you want to use Kotlin Reflection you'll also need to add compile "org.jetbrains.kotlin:kotlin-
reflect:$kotlin_version"
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 82
Section A.2: Using Android Studio
Android Studio can configure Kotlin automatically in an Android project.
To install the Kotlin plugin, go to File > Settings > Editor > Plugins > Install JetBrains Plugin... > Kotlin > Install, then
restart Android Studio when prompted.
Configure a project
Create an Android Studio project as normal, then press Ctrl + Shift + A . In the search box, type
"Configure Kotlin in Project" and press Enter.
Android Studio will alter your Gradle files to add all the necessary dependencies.
Converting Java
To convert your Java files to Kotlin files, press Ctrl + Shift + A and find "Convert Java File to Kotlin File".
This will change the current file's extension to .kt and convert the code to Kotlin.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 83
Section A.3: Migrating from Gradle using Groovy script to
Kotlin script
Steps:
build.gradle.kts
gradlew
gradlew.bat
settings.gradle
update the content of the build.gradle.kts based on your needs, you can use as inspiration the scripts in
the project just cloned or in one of its samples
now open Intellij and open your project, in the explorer window, it should be recognized as a Gradle project,
if not, expand it first.
after opening, let Intellij works, open build.gradle.kts and check if there are any error. If the highlighting is
not working and/or is everything marked red, then close and reopen Intellij
If you are on Windows, you may encounter this bug, download the full Gradle 3.3 distribution and use that instead
the one provided. Related.
LearnLoner.com
LearnLoner
GoalKicker.com – Kotlin® Notes for Professionals 84