Kotlin Example of Custom Iterable
/**
* Example of making custom class iterable
*/
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable<MyDate> {
override fun compareTo(other: MyDate): Int {
if (year != other.year) return year - other.year
if (month != other.month) return month - other.month
return dayOfMonth - other.dayOfMonth
}
}
operator fun MyDate.rangeTo(other: MyDate) = DateRange(this, other)
import java.util.Calendar
/*
* Returns the following date after the given one.
* For example, for Dec 31, 2019 the date Jan 1, 2020 is returned.
*/
fun MyDate.followingDate(): MyDate {
val c = Calendar.getInstance()
c.set(year, month, dayOfMonth)
val millisecondsInADay = 24 * 60 * 60 * 1000L
val timeInMillis = c.timeInMillis + millisecondsInADay
val result = Calendar.getInstance()
result.timeInMillis = timeInMillis
return MyDate(result.get(Calendar.YEAR), result.get(Calendar.MONTH), result.get(Calendar.DATE))
}
import java.util.*
import java.util.function.Consumer
class DateRange(val start: MyDate, val end: MyDate): Iterable<MyDate> {
override fun forEach(action: Consumer<in MyDate>?) {
super.forEach(action)
}
override fun iterator(): Iterator<MyDate> {
return object : Iterator<MyDate> {
var current: MyDate = start
override fun next(): MyDate {
if (!hasNext()) throw NoSuchElementException()
val result = current
current = current.followingDate()
return result
}
override fun hasNext(): Boolean = current <= end
}
}
override fun spliterator(): Spliterator<MyDate> {
return super.spliterator()
}
}
fun iterateOverDateRange(firstDate: MyDate, secondDate: MyDate, handler: (MyDate) -> Unit) {
for (date in firstDate..secondDate) {
handler(date)
}
}
< Go back to Kotlin section