DEV Community

Cover image for Convert Java to Kotlin using the Community Edition of IntelliJ
Hannu-Daniel Goiss
Hannu-Daniel Goiss

Posted on

Convert Java to Kotlin using the Community Edition of IntelliJ

I'm going to convert Java to Kotlin using the Community Edition of IntelliJ (2021.3.2). We'll look at the differences from the perspective of a Java developer.

The Java sample is from University of Texas: Java samples specifically this one: UnsortedHashSet sample

Converting Code from Java to Kotlin

I'll start by creating a new Kotlin project:
creating a new Kotlin Project
I am creating a new Kotlin file called UnsortedHashSet inside of this new project.
creating a new Kotlin File
I am now copy-pasting the java code from UnsortedHashSet Java sample into this file.
This automatically brings up a popup and asks if I want to convert the Java code to Kotlin.
Kotlin Code Conversion Popup
I obviously click on "Yes". This code segment is auto-created:

import java.util.*
class UnsortedHashSet<E> {
    private var size = 0
    private var con: Array<LinkedList<E>?>
    init {
        con = arrayOfNulls<LinkedList<*>?>(10) as Array<LinkedList<E>?>
    }
    fun add(obj: E): Boolean {
        val oldSize = size
        val index = Math.abs(obj.hashCode()) % con.size
        if (con[index] == null) con[index] = LinkedList()
        if (!con[index]!!.contains(obj)) {
            con[index]!!.add(obj)
            size++
        }
        if (1.0 * size / con.size > LOAD_FACTOR_LIMIT) resize()
        return oldSize != size
    }
    private fun resize() {
        val temp = UnsortedHashSet<E>()
        temp.con = arrayOfNulls<LinkedList<*>?>(con.size * 2 + 1) as Array<LinkedList<E>?>
        for (i in con.indices) {
            if (con[i] != null) for (e in con[i]!!) temp.add(e)
        }
        con = temp.con
    }
    fun size(): Int {
        return size
    }
    companion object {
        private const val LOAD_FACTOR_LIMIT = 0.7
    }
}
Enter fullscreen mode Exit fullscreen mode

I adjust the auto-generated main function to use the UnsortedHashSet class.

fun main(args: Array<String>) {
    println("Hello World!")
    var ush = UnsortedHashSet<String>()
    ush.add("Hannu Goiss")
    ush.add("Test Name")
    ush.add("another name")
    println("ush size: " + ush.size())
}
Enter fullscreen mode Exit fullscreen mode

I execute this and get the following output:

Hello World!
ush size: 3

Process finished with exit code 0
Enter fullscreen mode Exit fullscreen mode

EXCELLENT! The conversion was successful and the code can be executed!

Java vs Kotlin

Let's compare the Java & Kotlin code segments:

1. Variable declaration
Java code:

    private static final double LOAD_FACTOR_LIMIT = 0.7;

    private int size;
    private LinkedList<E>[] con;
Enter fullscreen mode Exit fullscreen mode

Kotlin code:

private var size = 0
private var con: Array<LinkedList<E>?>
Enter fullscreen mode Exit fullscreen mode

The converter put the static value at the end:

companion object {
    private const val LOAD_FACTOR_LIMIT = 0.7
}
Enter fullscreen mode Exit fullscreen mode

Observations:

  • We don't need the ";"
  • In Kotlin there is a difference between var and val. Val is used for the static value. Interestingly the converter is later using val for Java variables as well and can to figure out that those contain values that are never changing.

2. The Constructor
Java Code:

    public UnsortedHashSet() {
        con  = (LinkedList<E>[])(new LinkedList[10]);
    }
Enter fullscreen mode Exit fullscreen mode

Kotlin Code:

init {
    con = arrayOfNulls<LinkedList<*>?>(10) as Array<LinkedList<E>?>
}
Enter fullscreen mode Exit fullscreen mode

Observations:
We could have probably written more compact code: Declaring Classes in Kotlin

3. The "add" function
Java Code:

    public boolean add(E obj) {
        int oldSize = size;
        int index = Math.abs(obj.hashCode()) % con.length;
        if(con[index] == null)
            con[index] = new LinkedList<E>();
        if(!con[index].contains(obj)) {
            con[index].add(obj);
            size++;

        }
        if(1.0 * size / con.length > LOAD_FACTOR_LIMIT)
            resize();
        return oldSize != size;
    }
Enter fullscreen mode Exit fullscreen mode

Kotlin Code:

fun add(obj: E): Boolean {
    val oldSize = size
    val index = Math.abs(obj.hashCode()) % con.size
    if (con[index] == null) con[index] = LinkedList()
    if (!con[index]!!.contains(obj)) {
        con[index]!!.add(obj)
        size++
    }
    if (1.0 * size / con.size > LOAD_FACTOR_LIMIT) resize()
    return oldSize != size
}
Enter fullscreen mode Exit fullscreen mode

Observations:
oldSize and index are declared as val and not as var. This is good, as both values never change.

4. The "resize" function
Java Code:

    private void resize() {
        UnsortedHashSet<E> temp = new UnsortedHashSet<E>();
        temp.con = (LinkedList<E>[])(new LinkedList[con.length * 2 + 1]);
        for(int i = 0; i < con.length; i++){
            if(con[i] != null)
                for(E e : con[i])
                    temp.add(e);
        }
        con = temp.con;
    }
Enter fullscreen mode Exit fullscreen mode

Kotlin Code:

private fun resize() {
    val temp = UnsortedHashSet<E>()
    temp.con = arrayOfNulls<LinkedList<*>?>(con.size * 2 + 1) as Array<LinkedList<E>?>
    for (i in con.indices) {
        if (con[i] != null) for (e in con[i]!!) temp.add(e)
    }
    con = temp.con
}
Enter fullscreen mode Exit fullscreen mode

Observations:

  • the for-loop has a different syntax. But in general, it looks similar.
  • arrayOfNulls is definitely something new!
  • !! is an interesting way to access one element in an array.
  • the syntax with ... as ... is something to get used to.

5. The "size" function
Java Code:

    public int size() {
        return size;
    }
Enter fullscreen mode Exit fullscreen mode

Kotlin Code:

fun size(): Int {
    return size
}
Enter fullscreen mode Exit fullscreen mode

Observations:
This function didn't change much, except the slightly different syntax.

General Observations

  • 44 lines of code reduced to 39. those reductions are mainly due to different syntax for control structures. If we would be manually creating this code, we could have written much more compact code.
  • The syntax is different, so it requires some adjustment when creating code. But the syntax is so similar, that reading the code is easy. New concepts like "!!" are easy to understand at first glance.

The following link gives an overview of differences between Kotlin and Java (Java vs Kotlin) and the issues addressed in Kotlin. One key selling point is interoperability.

When you learn a new programming language, never just blindly convert code. You might create new issues: DON'T DO THIS
But it's for sure a good way to look at differences and get to know Kotlin.

I'm looking forward to coding in Kotlin.

Discussion (0)