Search code examples
kotlingenericsinterface

Understanding Kotlin function


I'm having some problem understanding Kotlin class.

internal class TransformingSequence<T, R>
constructor(private val sequence: Sequence<T>, private val transformer: (T) -> R) : Sequence<R> {
    override fun iterator(): Iterator<R> = object : Iterator<R> {
        val iterator = sequence.iterator()
        override fun next(): R {
            return transformer(iterator.next())
        }

        override fun hasNext(): Boolean {
            return iterator.hasNext()
        }
    }

    internal fun <E> flatten(iterator: (R) -> Iterator<E>): Sequence<E> {
        return FlatteningSequence<T, R, E>(sequence, transformer, iterator)
    }
}

In the above code, I don't understand what iterator() function is doing. It seems like the function is inheriting from Iterator interface, and returning an object(?) inheriting Iterator interface...? And I don't get 'val iterator = sequence.iterator()' is for. Can somebody help? Thank you in advance.


Solution

  • This is an object expression. It creates anonymous implementation of the Iterator interface and returns an instance of this class.

    Inside curly braces there is a standard class definition, and it can access variables from the outer scope. Therefore, val iterator = sequence.iterator() simply creates a property in this class.

    This code is an equivalent to:

    internal class TransformingSequence<T, R>
    constructor(private val sequence: Sequence<T>, private val transformer: (T) -> R) : Sequence<R> {
        override fun iterator(): Iterator<R> = MyIterator()
        
        private inner class MyIterator : Iterator<R> {
            val iterator = sequence.iterator()
            override fun next(): R {
                return transformer(iterator.next())
            }
    
            override fun hasNext(): Boolean {
                return iterator.hasNext()
            }
        }
    }
    

    From the high-level perspective, this class wraps an iterator inside another iterator and transforms all items on-the-fly. Whenever we ask for a next item from the wrapper iterator, it asks the internal iterator, transforms the item and returns.