Kotlin'icum - cheat sheet

java
node
kotlin
tenary
native
jvm
gradle
libgdx
full-stack
spring
coding
spark
Tags: #<Tag:0x00007f0ca9fd8f38> #<Tag:0x00007f0ca9fd8c68> #<Tag:0x00007f0ca9fd87b8> #<Tag:0x00007f0ca9fd82e0> #<Tag:0x00007f0ca892fbb0> #<Tag:0x00007f0ca892f750> #<Tag:0x00007f0ca892f3b8> #<Tag:0x00007f0ca892ef08> #<Tag:0x00007f0ca892eb48> #<Tag:0x00007f0ca892e5a8> #<Tag:0x00007f0ca892def0> #<Tag:0x00007f0ca892db30>

#1

This is an incomplete Wiki section about Kotlin programming. I need to find time to correct it and to explain the code snippets properly. Until then it’s my personal copy-paste reference. The goal is to shed some light on full-stack Kotlin, which I am using for a hobby project.


##Table of Contents

Kotlin - developer productivity in mind and code

Assumptions

This is a knowledge-base Wiki entry. Not a tutorial. It assumes readers know:

  • Java EE, Spring, Tomcat
    • Spring Security, …
  • JavaScript (ES6)
  • SQL and NoSQL databases
  • Kotlin basics
  • Maven and Gradle
  • Functional Programming, Reactive Programming
  • Docker and some JVM memory-internals
  • Kubernetes
  • Linux, Bash / ZSH, …
  • DevOps pipelines with Jenkins
  • GUI application life-cycles
  • :slight_smile:

At least to some degree, like any software engineer does. If you have a question, please try Stackoverflow etc… I only use these Wiki pages as a notepad.

Use cases for Kotlin as a general purpose language

Kotlin is not just for Android Studio

Besides Android application development (I focus on “Progressive Web Applications” (PWAs) for the time being) I intend to use Kotlin for what some people may refer to as “Full Stack” development:

  • next-gen Spring Boot / Java EE development (Java language interop)
    • WebFlux[1] and RESTful services (for Micro-service architectures, CQRS etc.)
    • OrientDB (NoSQL) with JPA[2], as well as PostgreSQL
  • Kotlin for JS[3] for React and / or Angular

Outside of general Web App Dev:

  • Data-analysis workflows with Apache Spark (RDDs for data-mapping, “Machine Learning” with MLlib, better functional programming than with Java 8 lambdas)
    • or for local data analysis with krangl[4], which is like Pandas
  • We can use Kotlin with Node.js (ES6 interop, like with ts-node)[5]
  • building static (portable) native Linux tools for automation (using APIs for DevOps automation mostly)[6] (libcurl)
  • using the Gradle Kotlin DSL for build automation[7]
  • and look at ways to use Electron from Kotlin JS, or better at libGDX[8]. But generally I don’t intend to focus on X-platform Desktop GUIs here

Kotlin is very versatile, yet simple to learn. If you have a Java and Python background, welcome to the future…

  • Kotlin works with general JVM style DevOps pipelines for CI / CD (Thin WAR or JAR with Docker base-images and k8s deployments for example)
  • You can optimize a JVM based Micro-Service for memory-efficient ans responsive behaviour, but of course…

Kotlin is not perfect. No single language is.

Version infos etc.

From my pom.xml (I use Maven for some projects as well):

    <properties>
        <java.version>1.8</java.version>
        <kotlin.version>1.2.71</kotlin.version>
    </properties>

Some of my projects are on 1.3 already.

Resources

Unchecked exceptions are not Java-like

Exceptions in Kotlin are unchecked. – That means you will not be forced to add the throws keyword to your functions (funs in the following).
This also means, that safety-net you might be accustomed to from Java coding is not there.

One good reason is, that there is a certain emphasis on functional programming, and unless you really push it you will have a hard to getting the typical NullPointerException (NPEs) with Kotlin code.

try-catch-finally

This shoild appear to be familiar:

try {
   println(1 / 0)
catch (e : ArithmeticException) {
   println("caught")
finally {
   println("qed")
}

Or, if you want to throw an Exception, take a look at this piece of valid code:

fun divide(a : Int, b : Int) : Double {
   Thread.sleep(1000)
   return(a as Double / b)
}

Yes, that will compile (as indicated in the previous paragraph), and you are not forced to throw an InterrupedException. – For Java interoperability (hint: reflection) you have to annotate the fun:

@throws(InterruptedException::class)
fun divide(a : Int, b : Int) : Double {
...

Keep in mind: if you want to use the Kotlin classes from within Java code you have to annotate them properly.

try as shorthand expression on functions

This will do:

    fun foo() : Int {
        return try {
            return 1
        } catch (e: Exception) {
            return 0
        }
    }

– As a comprised example of the syntax, of course :slight_smile:

Simple nested try-catch-finally blocks are supported and the result can be used directly in vals and vars.

Try with resources

This is a Java >= 8 style feature; exemplified with the following Java code:

try(FileInputStream fis = new FileInputStream("foo.txt")) {...}

You have to throw the IOException at the function level (not listed), but you don’t need nested try-catch-finally blocks in Java >= 8 code.

The use expression for Kotlin-style exception handling

Here is the Kotlin-variant of try-with-resources

    import java.io.FileInputStream

    fun printFile() {
        val fis = FileInputStream("foo.txt")
        fis.use {
            // exception would autoclose the FileInputStream
        }
    }

This is good-style Kotlin.

TDD with JUnit5 for Kotlin development

JUnit >= 5 works with Kotlin, and it’s just like Java.

– Couple of things first: if you can, just use the Kotlin test classes. Check the imports here in the code listing and don’t worry about the missing syntactic sugar.

    package kotlin_tdd

    import org.junit.jupiter.api.Test
    import java.util.*
    import kotlin.test.assertEquals

    class AgeCalc() {
        fun getAge(dob: Calendar): Int {
            return 0
        }
    }

    class AgeCalcTests() {
        @Test
        fun checkAgeWhenBornToday() {
            assertEquals(
                0,
                AgeCalc().getAge(Calendar.getInstance())
            )
        }
    }

There are a couple of assertions I wouldn’t recommend to use… but you can test-drive your code with JUnit.

Kotlin data classes

In Kotlin you can create data class objects[9] to get Java-like .equals() or .hashCode() funs. Plus destructors. Plus Getters and Setters. – Of course you can override these, if there is a need.

Declaration is simple enough:

data class Person(
    val id: Long,
    val title: String,
    val firstName: String,
    val surName: String,
    val dob: Calendar?
) {...

If, let, elvis, tenary, null-safe checks and a ?

This is a bit heavier…

Java example code - control flow

Plain Java code:

    if (someExpr) {
      return xyz;
    } else {
      return zzt;
    }

The Ternary operator in Kotlin and Java

Also plain Java code, semantically the same:

return someExpr ? xyz : zzt;

Use if in a function-like way in Kotlin

If in Kotlin can be expressed in a function-like (similar to using try-catch directly as a return statement):

    return if (someExpr) {
       xyz
    else {
       zzt
    }

There is no ternary op in Kotlin, but a shorthand syntax that is almost the same:

return if(someExpr) xyz else zzt

Or, just to be clear:

val foo = if(someExpr) xyz else zzt

The elvis operator versus Kotlin smart-casts

Kotlin has got the Ruby-like elvis op:

    val safeXyz : Int
       get() {
          return xyz ?: -1
        }

It can be used for Null-safety checks this way, because Kotlin won’t smart-cast Null-able objects (indicated with a ?).

Let’s say Person gets a var favColour : String? = null property. The Getter can use the elvis op:

    fun getFavColour() : String {
       return favColour? ?: ""
    }

elvis and it (lambda expressions) in Kotlin

In case favColour is null the following Getter returns an empty String. In case you need to pass the exemplified favColour variable to another function first, you cannot use the elvis op (don’t !! stuff) without Kotlin’s let function.

    fun getFavColour() : String {
       return favColour?.let ( getLastLetter(it) ) ?: ""
    }

Easy, right… it is a shorthand for a lambda expression like x -> x. You may see code like this that iterates over a Collection using it:

(0..9 step 2).forEach { println(it) }

As long as there’s an Iterator, this will work. Intuitive enough…

The let function and the evlis op for null-safe checks

    // not immutable
    var petname : String? = null

    fun getLastLetter(a : String) = a.takeLast(1)

    // nope!
    fun getLastLetterOfPet() =
        return if (petname == null) "" else getLastLetter(petname)

    fun main(args: Array<String>) {
        println(getLastLetter("hello")
    }

Copy-paste that into an IDE, and check it out. Won’t work, because petname may be null. If you add !! it still may be null, and trigger an exception.

package let_stuff

// not immutable, may be null
var petname : String? = null

fun getLastLetter(a : String) = a.takeLast(1)

// fixed :)
fun getLastLetterOfPet() : String {
    return petname?.let { getLastLetter(it) } ?: ""
}

fun main(args: Array<String>) {
    println(getLastLetter("hello"))
    println(getLastLetter(getLastLetterOfPet()))
}

If petname is not null we are using the let function. If it’s null we must return something, which is an empty String.
The let function here is used to do the null check and the elvis operator does the safety check.

Object equality

This is PHP-like.

  • Reference ===
  • Value ==, or .equals()

Functional programming

package functional.Utils

fun someStringMagic(inputString: String, functionArg: (String) -> String) : String =
        functionArg(inputString)

fun main(args: Array<String>) {
    val result = someStringMagic(
        "oh hai") { x ->  x[0].toUpperCase() + x.substring(1) }
    println(result)
}

Mapping with Kotlin

package functional.Utils

fun main(args: Array<String>) {
    val cables = listOf("usb", "hdmi", "vga", "scart", "usb-c")

    // one to one
    val upperCaseCables = cables.map { it.toUpperCase() }
    val usbCables = upperCaseCables.filter { it.contains("usb".toUpperCase()) }
    usbCables.forEach { println(it) } // curly

    // one to n
    upperCaseCables.flatMap {
        if (it.contains("USB")) listOf(it, it.toLowerCase()) else listOf(it)
    }
        .forEach { println(it) }
}

Using fold on Collections

    val numbers = cables.map { it.length }
    println(numbers.sum())
    println(numbers.average())
    println(numbers.count())
    println(numbers.fold(0) { result, value -> result + value })
    // maximum
    println(numbers.fold(0) { result, value -> if (value > result) value else result })

Using maps in Kotlin and process Strings

    val myMap = mapOf(1 to "one", 2 to "two", 3 to "three")
    myMap.filter { (k,v) -> v.startsWith("o") }.forEach{ (k,v) -> println("$k, $v")}

Here the Map object gets destructured into k and v. The fold() functions take two parameters.

Reflection ::

Looking inside a class is reflection.

import java.lang.Math.sqrt
import kotlin.math.roundToInt


fun isPrime(a : Int) : Boolean {
    val maxNumToChk = sqrt(a.toDouble()).roundToInt()
    for (i in 2..maxNumToChk) if (a % i == 0) return false
    return true
}

fun main(args: Array<String>) {

    val myList = listOf(14, 22, 3, 88, 96, 17, 19)
    println(myList::class::qualifiedName)

    val primeNums = myList.filter { isPrime(it) }
    println(primeNums)

    val primeNums2 = myList.filter ( ::isPrime )
    println(primeNums2)

}

Use Reflection for a Logger configuration

I may have a Logger per class… and you know…

val log = Logger(MyClass::class:java.simpleName, Logger.DEBUG)

Kotlin, Spring 5 and JPA

Compiler plugins for JPA with Gradle plugin hooks

For JPA you need to use two compiler plugins[10], which you can do with a Gradle:

plugins {
  id "org.jetbrains.kotlin.plugin.jpa" version "1.3.11"
  id "org.jetbrains.kotlin.plugin.noarg" version "1.3.11"
  id "org.jetbrains.kotlin.plugin.allopen" version "1.3.11"
}

Hibernate instantiates the Entity first (with default values), and if you use vals in your constructor classes you may face a compatibility issue. Using these plugins enables you to keep the variables immutable for everything except Hibernate.

Reactive Programming

Reactive Programming is a big deal, also with Spring >= 5 and Kotlin. Want to see some code? – Sure you do.

With “Reactive Programming” I refer to the async non-blocking programming techniques.

Simple example on Reactive Programming with Kotlin

Gradle - RxJava2 and RxKotlin2

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    // https://mvnrepository.com/artifact/io.reactivex.rxjava2/rxjava
    compile group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.2.5'
    // https://mvnrepository.com/artifact/io.reactivex.rxjava2/rxkotlin
    compile group: 'io.reactivex.rxjava2', name: 'rxkotlin', version: '2.3.0'
}

I indicate that I am using RxJava / RxKotlin, but there are other libs worth checking out. These are good for beginners.

Simple example

This is simple code to get the hang of it:

import io.reactivex.Observable
import kotlin.collections.Map.Entry

class fakeDB {

    fun getUsers() : Observable<Entry<Int, String>> {
        return Observable.fromIterable(
            mapOf(
                1 to "Jim",
                2 to "Lui",
                3 to "Troll"
            ).entries
        )
    }
}

fun main(args: Array<String>) {

    val db = fakeDB()

    // display all user's name
    db.getUsers()
        .map { user -> user.value }
        .subscribe({name -> println(name)})

}

As you know in Kotlin you can have functions outside of classes and you can have multiple classes per file in a project.

If the first comment that comes to your mind is, that I should have used println(it) as opposed to name -> println(name) you are right.

libGDX and Java inter-operability

Kotlin lateinit and Null-able types

Some Java classes may belong to frameworks with their own (real) dependencies, like signal handlers (for GUIs), listeners, socket instances, … From these frameworks you may get Null-able properties, that get initialized via Dependency Injection or via a setup for a Unit Test. Therefore initializing these properties needs to happen with lateinit. Here is an example for libGDX, just to exemplify this:

import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch

class MyGdxGame : ApplicationAdapter() {

    lateinit var batch : SpriteBatch
    lateinit var img : Texture


    override fun create() {
        batch = SpriteBatch()
        img = Texture("badlogic.jpg")

    }

The two classes Texture and SpriteBatch have external resources. lateinit is used to indicate a later initialization, that will happen with a framework function (here create()). This way you remain safe of NPEs and you can interoperate with Java / external resources.

Kotlin and Node

Gradle for KotlinJS to compile to ES6

Kotlin and Apache Spark

Native Kotlin

Threads and API Requests

Use a compiled Kotlin library from Python

Appendix

Changelog

3.1.2019 - started wiki
Process finished with exit code 0


  1. https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html ↩︎

  2. https://orientdb.com/docs/2.1.x/JPA-Configuration.html ↩︎

  3. https://kotlinlang.org/docs/reference/js-overview.html ↩︎

  4. https://github.com/holgerbrandl/krangl ↩︎

  5. https://medium.com/@Miqubel/your-first-node-js-app-with-kotlin-30e07baa0bf7 ↩︎

  6. https://github.com/JetBrains/kotlin-native/tree/master/samples/libcurl ↩︎

  7. https://blog.gradle.org/kotlin-meets-gradle ↩︎

  8. https://libktx.github.io/ ↩︎

  9. https://kotlinlang.org/docs/reference/data-classes.html ↩︎

  10. https://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support ↩︎