문제

A Kotlin for loop can iterate through any object if the corresponding iterator member or extension function is available.

Make the class DateRange implement Iterable, so that it can be iterated over. Use the function MyDate.followingDate() defined in DateUtil.kt; you don't have to implement the logic for finding the following date on your own.

Use an object expression which plays the same role in Kotlin as an anonymous class in Java.

class DateRange(val start: MyDate, val end: MyDate)

fun iterateOverDateRange(firstDate: MyDate, secondDate: MyDate, handler: (MyDate) -> Unit) {
    for (date in firstDate..secondDate) {
        handler(date)
    }
}

class DateRange(val start: MyDate, val end: MyDate) : Iterable<MyDate> {
    override fun iterator() : Iterator<MyDate> {
        // hasNext, next 구현이 되어야 됨
        return object : Iterator<MyDate> {
            var current: MyDate = start

            override fun hasNext(): Boolean = current <= end

            override fun next() : MyDate {
                // 다음 요소가 없으면 예외 던지기
                if(!hasNext()) throw NoSuchElementException()
                val result = current
                current = current.followingDate()
                return result
            }
        }
    }
}

fun iterateOverDateRange(firstDate: MyDate, secondDate: MyDate, handler: (MyDate) -> Unit) {
    for (date in firstDate..secondDate) {
        handler(date)
    }
}

풀이

DateRange 클래스를 Iterable<MyDate>로 구현하여 for 를 통해 처리를 반복할 수 있도록 만드는 문제이다.

Iterator는 객체를 반복해서 읽어오는 객체다. 즉, 구현과 분리하여 처리를 반복하는 것이다.

Iterator 메서드

  • hasNext() : 읽어올 요소가 남아있는지 확인(next 호출 전에 확인 해야 됨)
  • next() : 다음 요소를 읽어 옴

Iterator확인, 읽기 순으로 요소들을 읽어오기 때문에

hasNext()를 통해 요소를 먼저 확인하고 next()를 통해 값을 읽어와야 한다.

먼저 hasNext()를 오버라이드 한다. <= 연산자를 이용해서 요소를 확인한다.

MyDate 클래스가 Comparable<MyDate> 인터페이스를 구현하고 있으므로 두 날짜 객체를 비교할 수 있기 때문이다. <= 연산자는 compareTo 메서드를 통해 두 날짜 객체를 비교하여 현재 날짜가 마지막 날짜보다 작거나 같은지를 확인한다.

그 다음으로 next()를 오버라이드한다.

hasNext()가 없다면 다음에 읽어올 요소가 없다는 뜻이므로 예외를 던지도록 한다.

  • current는 현재 반복 중인 요소를 나타내고,
  • result는 현재 요소를 저장하여 next() 메서드가 호출된 후 반환할 값을 보관한다.

최종적으로 result를 반환하게 되면 next() 메서드가 호출될 때마다 현재 요소를 반환하고, 다음 요소로 업데이트할 수 있다.

profile
개발하는 다람쥐

0개의 댓글