코틀린 & Java/코틀린인액션

Kotlin 범위 관례 인덱스로 원소 접근 Get, Set

코딩하는후운 2023. 5. 9. 13:27
반응형

범위 관례

인덱스로 원소 접근 Get, Set

  • 콜렉션에서 가장 많이 쓰이는 연산은 인덱스를 이용해 읽고 쓰는 연산
  • 자바에서 배열 원소에 접근할때 [ ] 를 사용하는 것처럼 코틀린의 맵에서도 이를 사용한다.
callbackParamMap["success"] = true

/**
 * Allows to use the index operator for storing values in a mutable map.
 */
@kotlin.internal.InlineOnly
public inline operator fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit {
    put(key, value)
}


class ExampleUnitTest {

    @Test
    fun test() {
        val list = mutableListOf("A", "B", "C")
        println(list)
        list[0] = "D"
        println(list)

        val map = mutableMapOf(0 to "A", 1 to "B", 2 to "C")
        println(map)
        map[0] = "D"
        println(map)
    }
}
class ExampleUnitTest {

    @Test
    fun test() {
        val position = Position(10, 20)
        println(position)
        position[0] = 30 -> set
        println(position)
        println(position[1]) -> get
    }
}

data class Position(var a: Int, var b: Int) {

    operator fun set(position: Int, value: Int) {
        when (position) {
            0 -> a = value
            1 -> b = value
            else -> throw IndexOutOfBoundsException("Invalid $position")
        }
    }

    operator fun get(position: Int): Int = when (position) {
        0 -> a
        1 -> b
        else -> throw IndexOutOfBoundsException("Invalid $position")
    }
}

In 관례

  • in 은 객체가 컬렉션에 들어있는지 검사한다.
  • in 연산자와 대응하는 함수는 contains

a in c → c.contains(a)
a in x until y : a 가 x 이상 y 미만
a in x .. y : a 가 x 이상 y 이하

iterator, rangeTo 관례

  • 이터레이터를 얻은다음 이터레이터에대해 hasNext 와 next 호출을 반복하는식으로 변환됨
for(i: Int in 1..10)
for(item in itemList) 



/**
 * An iterator over a collection or another entity that can be represented as a sequence of elements.
 * Allows to sequentially access the elements.
 */
public interface Iterator<out T> {
    /**
     * Returns the next element in the iteration.
     */
    public operator fun next(): T

    /**
     * Returns `true` if the iteration has more elements.
     */
    public operator fun hasNext(): Boolean
}


override fun iterator(): IntIterator = IntProgressionIterator(first, last, step)


/** An iterator over a sequence of values of type `Int`. */
public abstract class IntIterator : Iterator<Int> {
    override final fun next() = nextInt()

    /** Returns the next value in the sequence without boxing. */
    public abstract fun nextInt(): Int
}

/**
 * An iterator over a progression of values of type `Int`.
 * @property step the number by which the value is incremented on each step.
 */
internal class IntProgressionIterator(first: Int, last: Int, val step: Int) : IntIterator() {
    private val finalElement: Int = last
    private var hasNext: Boolean = if (step > 0) first <= last else first >= last
    private var next: Int = if (hasNext) first else finalElement

    override fun hasNext(): Boolean = hasNext

    override fun nextInt(): Int {
        val value = next
        if (value == finalElement) {
            if (!hasNext) throw kotlin.NoSuchElementException()
            hasNext = false
        }
        else {
            next += step
        }
        return value
    }
}
operator fun ClosedRange<LocalData>.iterator(): Iterator<LocalDate> =
	object : Iterator<LocalDate> { // 이 객체는 LocalDate 원소에 대한 iterator를 구현한다.
		var current = start
		override fun hasNext() =
			current <= endInclusive // compareTo 관례를 사용해 날짜를 비교한다.
		override fun next() = current.apply {
			current = plusDays(1)
		} // 현재 날짜를 저장한 다음에 날짜를 변경한다. 그 후 저장해둔 날짜를 반환한다.
	}
}

>> val newYear = LocalDate.ofYearDay(2017,1)
>> val daysOff = newYear.minusDays(1)..newYear
>> for (dayOff in daysOff) { println(dayOff) }

2016-12-31
2017-01-01


/**
 * Represents a range of values (for example, numbers or characters) where both the lower and upper bounds are included in the range.
 * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/ranges.html) for more information.
 */
public interface ClosedRange<T : Comparable<T>> {
반응형