Popular Questions and Answers in Kotlin
Author:
Views:
Category:
Kotlin
Popular Questions and Answers in Kotlin
What is the equivalent of Java static methods in Kotlin?

You place the function in the companion object.

So the java code like this:

class Foo {
  public static int a() { return 1; }
}

will become

class Foo {
  companion object {
     fun a() : Int = 1
  }
}

You can then use it from inside Kotlin code as

Foo.a();

But from within Java code, you would need to call it as

Foo.Companion.a();
What is the @JvmStatic annotation in Kotlin?

If you don't like having to specify the Companion bit you can either add a @JvmStatic annotation or name your companion class.

Adding the @JvmStatic annotation looks like this

class Foo {
  companion object {
    @JvmStatic
    fun a() : Int = 1;
  }
}

and then it will exist as a real Java static function, accessible from both Java and Kotlin as Foo.a().

However, on the JVM you can have members of companion objects generated as real static methods and fields, if you use the @JvmStatic annotation.

What is the equivalent of ternary conditional operator in Kotlin?
 //Ternary conditional operator
a ? b : c

This is not valid code in Kotlin.

In Kotlin, if statements are expressions. So the following code is equivalent:

if (a) b else c

The distinction between expression and statement is important here. In Java/C#/JavaScript, if forms a statement, meaning that it does not resolve to a value. More concretely, you can't assign it to a variable.

// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c

If you're coming from a language where if is a statement, this might seem unnatural but that feeling should soon subside.

Additionally you can also use when in kotlin.

How to check if a lateinit variable has been initialized?

There is a lateinit improvement in Kotlin 1.2 that allows to check the initialization state of lateinit variable directly:

lateinit var lateinitVar: String 
println("isInitialized before assignment: " + this::lateinitVar.isInitialized)
lateinitVar = "value"
println("isInitialized after assignment: " + this::lateinitVar.isInitialized)

Output will be

isInitialized before assignment: false
isInitialized after assignment: true
differences between lateinit var and by lazy { ... }?

Here are the differences between lateinit var and by lazy { ... } delegated property:

  • lazy { ... } delegate can only be used for val properties, whereas lateinit can only be applied to vars, because it can't be compiled to a final field, thus no immutability can be guaranteed
  • lateinit var has a backing field which stores the value, and by lazy { ... } creates a delegate object in which the value is stored once calculated, stores the reference to the delegate instance in the class object and generates the getter for the property that works with the delegate instance. So if you need the backing field present in the class, use lateinit
  • In addition to vals, lateinit cannot be used for non-nullable properties and Java primitive types (this is because of null used for uninitialized value)
  • lateinit var can be initialized from anywhere the object is seen from, e.g. from inside a framework code, and multiple initialization scenarios are possible for different objects of a single class. by lazy { ... }, in turn, defines the only initializer for the property, which can be altered only by overriding the property in a subclass. If you want your property to be initialized from outside in a way probably unknown beforehand, use lateinit.
  • Initialization by lazy { ... } is thread-safe by default and guarantees that the initializer is invoked at most once. In the case of lateinit var, it's up to the user's code to initialize the property correctly in multi-threaded environments.
  • A Lazy instance can be saved, passed around and even used for multiple properties. On contrary, lateinit vars do not store any additional runtime state (only null in the field for uninitialized value).
What is the difference between const and val?

consts are compile time constants. Meaning that their value has to be assigned during compile time, unlike vals, where it can be done at runtime.

This means, that consts can never be assigned to a function or any class constructor, but only to a String or primitive.

For example:

const val foo = complexFunctionCall()   //Not okay

val fooVal = complexFunctionCall()  //Okay

const val bar = "Hello world"       //Also okay
How to initialize an array in Kotlin with values?

In Java an array can be initialized such as:

int numbers[] = new int[] {10, 20, 30, 40, 50};

Same in kotlin an array initialization look like

val numbers: IntArray = intArrayOf(10, 20, 30, 40, 50)

Initializing a list is very similar:

val numbers = listOf(10, 20, 30, 40, 50)
For more about collections
How do I initialize Kotlin's MutableList to empty MutableList?

You can simply write:

val mutableList = mutableListOf()

Alternative ways are

val mutableList : MutableList = arrayListOf()
  
or

val mutableList : MutableList = ArrayList()

This is exploiting the fact that java types like ArrayList are implicitly implementing the type MutableList via a compiler trick.

How to Sort collection by multiple fields in Kotlin?

Use sortedWith to sort a list with Comparator like.

val sortedList = list.sortedWith(compareBy({ it.age }, { it.name }))

You can also use the somewhat more succinct callable reference syntax:

val sortedList = list.sortedWith(compareBy(Person::age, Person::name))

for descending sort use simply minus like

val sortedList = list.sortedWith(compareBy({ -it.age }, { -it.name }))
Kotlin's List missing add, remove, Map missing put, etc?

In Java we could do the following

public class TempClass {
    List myList = null;
    void doSomething() {
        myList = new ArrayList<>();
        myList.add(10);
        myList.remove(10);
    }
}

But if we rewrite it to Kotlin directly as below

class TempClass {
    var myList: List? = null
    fun doSomething() {
        myList = ArrayList()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

We will get the error of not finding add and remove function from that List

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. So, we'll need to use a MutableList list.

class TempClass {
    var myList: MutableList = mutableListOf()
    fun doSomething() {
        // myList = ArrayList() // initializer is redundant
        myList.add(10)
        myList.remove(10)
    }
}

MutableList = arrayListOf() should also work.