Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Linked List in Kotlin

I've recently started learning Kotlin, so I decided to implement some data structures in it. So, I've tried implementing a singly linked list:

package datastructures

public class LinkedList {
    private data class Node(var nodeValue: Int, var next: Node? = null)
    private var head: Node? = null

    fun insert(n: Int) {
        if(head == null) head = Node(n)
        else {
            var cur = head
            while(cur?.next != null) {
                cur = cur?.next
            }
            cur?.next = Node(n)
        }
    }

    fun print() {
        var cur = head
        while(cur != null) {
            print("${cur.nodeValue} ")
            cur = cur?.next
        }
    }

}

fun main(args: Array<String>) {
    val n = LinkedList()
    n.insert(5)
    n.insert(3)
    n.print()
}

and I got the following error:

Error:(22, 13) Kotlin: [Internal Error] org.jetbrains.jet.codegen.CompilationException: Back-end (JVM) Internal error: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack@a0a447f
Cause: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack@a0a447f
File being compiled and position: (22,13) in C:/Users/Khaled/IdeaProjects/Kotlin/src/LinkedList.kt
PsiElement: cur?.next = Node(n)
The root cause was thrown at: StackValue.java:75
    at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:243)
    at org.jetbrains.jet.codegen.ExpressionCodegen.genStatement(ExpressionCodegen.java:262)
    at ...

I've been searching here and in google but I can't figure out what's the problem causing this error

Edit: So I've tried to re-implement the insert function and use requireNotNull() to avoid having the compiler worry about the null-safety stuff.

Here is the code and it's now working:

fun insert(n: Int) {
    if (head == null) head = Node(n)
    else {
        var cur = head!!
        while (cur.next != null) {
            cur = cur.next!!
        }
        cur.next = Node(n)
    }
}
like image 418
Khaled Essam Avatar asked Sep 22 '14 03:09

Khaled Essam


1 Answers

I think the problem lies in this line:

cur?.next = Node(n)

The problem is that the compiler doesn't know what to do if cur is null. Currently, this results in internal error, but this may be supported in a future version.

For now, the best solution is to rewrite the code such that the compiler could check that cur is never null. The problem is that the compiler assumes that fields declared as var can change at any time, so their values need to be loaded into local variables before checking for null:

var cur = head
if(cur == null) head = Node(n)
else {
    var next = cur.next
    while(next != null) {
        cur = next
        next = cur.next
    }
    cur.next = Node(n)
}
like image 118
abacabadabacaba Avatar answered Nov 15 '22 10:11

abacabadabacaba