Home > Mobile >  How to implement iterator for a LinkedList using Kotlin
How to implement iterator for a LinkedList using Kotlin

Time:02-19

I am implementing LinkedList in Kotlin. I wanted to implement Iterator interface so that I can for each on the LinkedList like so linkedlist.forEach{}.

here is the code that I have

class SinglyLinkedList<T> : Iterator<T> {

    var head: SinglyLinkedListNode<T>? = null
        private set(value) {
            cursor = value
            field = value
        }

    var count = 0
        private set

    // This is needed for iterator functionality.
    private var cursor: SinglyLinkedListNode<T>? = null

 override fun hasNext(): Boolean {
        // the problem is when I return in the middle of the loop
        // then start new for each
        // cursor is not equal head
        return if (cursor == null){
           // if this is the last time, reset cursor so that next time we start from the begining
            cursor = head
            false
        } else {
            true
        }
    }
    override fun next(): T {
        val temp = cursor
        cursor = cursor!!.next
        return temp!!.value
    }
}

the issue happens when I do something like this

linkedlist.forEach{
 if(it) == 1 return
}

then I try to forEach again, it will continue from the last element it stopped at.

CodePudding user response:

then I try to forEach again, it will continue from the last element it stopped at.

Yes, that is what an Iterator is supposed to do. An Iterator is a stateful thing - it knows which element it is currently "at". Do you want your linked list to know which element it is currently "at"? You probably don't, do you? You want your linked list, and the iterator of that linked list, to be different things.

The list can be iterable, meaning that you can get an iterator from the list.

class SinglyLinkedList<T> : Iterable<T> {

    var head: SinglyLinkedListNode<T>? = null
        private set

    var count = 0
        private set

    override fun iterator() = object: Iterator<T> {
        private var cursor: SinglyLinkedListNode<T>? = head

        override fun hasNext() = cursor != null

        override fun next() = (cursor?.value ?: throw NoSuchElementException()).also {
            cursor = cursor?.next
        }
    }
}

Now doing forEach on the list will create an iterator of the list, and after iterating through the list (no matter which element you have iterated to), the iterator will be discarded. The next time you call forEach, a brand new iterator gets created.

  • Related