Iterator and Iterable interface in kotlin 以前一直不理解Iterable与Iteration的关系,在kotlin的语法里面,正好可以区别开。iterable是一个接口,需要一个函数实现它,并实现它的iterator方法,返回一个真正的iterator类。具体的迭代应该怎么做,需要传一个继承iterator接口的类。
示例:
data class MyDate (val year: Int ,val month: Int ,val dayOfMonth: Int )
需要注意的是,在实现迭代之前,需要实现comparable接口,这样可以使用<,<=,>,>=
这四个逻辑运算。
如下
data class MyDate (val year: Int , val month: Int , val dayOfMonth: Int ):Comparable<MyDate>{ override fun compareTo (other: MyDate ) =when { year != other.year -> year - other.year month != other.month -> month - other.month else -> dayOfMonth - other.dayOfMonth } }
那么在kotlin中,需要使用到迭代的地方一般是range函数中,所以,现在假设使用for循环迭代日期;
for (date in firstDate..secondDate) { handler(date) }
现在,语法糖部分..
也就是rangeTo()部分没有实现。rangeTo
这个内联函数很有意思,它接收一个MyDate类,作为end,因为上文中实现了比较,所以可以知道迭代的对象是否再range的闭区间 (与大多数语言不同,kotlin中的)rangTo函数实现的是左右闭区间的范围,和一般的左闭右开的区间范围很不同。如果需要用到左闭右开区间,可以使用until
语法糖。那么直接重载rangTo方法,让其返回一个继承iterable<T>接口的类。
operator fun MyDate.rangeTo (other: MyDate ) = DateRange(this , other)
那么接下来的需要实现这个继承iterable接口的类
class DateRange (val start: MyDate, val end: MyDate): Iterable<MyDate>{ override fun iterator () : Iterator<MyDate> = DateIterator(this ) }
最后实现继承iterator的类就好了,需要实现next(),hasNext()基本方法
class DateIterator (val dateRange:DateRange) : Iterator<MyDate> { var current: MyDate = dateRange.start override fun next () : MyDate { val result = current current = current.nextDay() return result } override fun hasNext () : Boolean = current <= dateRange.end }
总结 iterator和iterable接口是逻辑上是比较绕的,但是却能很好的将不同功能面的逻辑抽象分离出来,高内聚低耦合,很厉害。