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.