Kotlin Array의 메서드와 확장함수 파헤치기 (1)

김성준·2022년 12월 21일
0

Kotlin

목록 보기
14/17

코틀린 Array의 메서드와 확장 함수 파헤치기(1)

Array 클래스

package kotlin

public class Array<T> {
    public inline constructor(size: Int, init: (Int) -> T)

    public operator fun get(index: Int): T

    public operator fun set(index: Int, value: T): Unit

    public val size: Int

    public operator fun iterator(): Iterator<T>
}

Array 클래스는 위와 같은 구조로 이루어져 있습니다.

하나씩 차근차근 각 메서드가 무엇을 하는지 알아봅시다.

생성자(constructor) 메서드

생성자 메서드는 Array 클래스를 생성하는 역할을 합니다.

첫번째 인자로 생성할 배열의 크기를 입력받고, 두번째 인자로는 배열을 초기화 하는데 사용할 함수를 입력 받습니다.

fun main() {
	val array: Array<Int> = Array(5) { idx: Int -> idx * idx }
}

이렇게 생성자 메서드를 사용하여 간단하게 배열을 생성하고 초기화까지 할 수 있습니다. 위의 예제는 size가 5인 배열을 만들고, 각 요소를 인덱스의 제곱으로 초기화 하는 코드입니다.

이렇게 생성된 배열은 [0, 1, 4, 9, 16]이 됩니다.

get 메서드

get 메서드는 연산자 오버로딩(operator)가 사용되고 있습니다. 따라서 [index] 형식의 연산자를 사용하여 호출 가능합니다.

해당 index에 들어있는 값을 반환합니다.

fun main() {
	val array: Array<Int> = Array(5) { idx: Int -> idx * idx }

	println(array[3]) // 9
    println(array.get(3)) // 9
}

예제에서 처럼 두 가지 형태로 사용 가능하고, 똑같은 역할을 합니다. 둘 중에 편한 방법으로 사용하면 되지만 보다 권장되는 방법은 첫번째 방법입니다.

set 메서드

set 메서드도 get 메서드와 마찬가지로 연산자 오버로딩이 사용됩니다. [index] = value 형식의 연산자를 사용할 수 있습니다.

이 메서드는 해당 index의 값을 인자에 넣은 값으로 변경하는 역할을 합니다.

fun main() {
	val array: Array<Int> = Array(5) { idx: Int -> idx * idx }

	array[3] = 4
    array.set(3, 4)
	println(array[3]) // 4
    println(array.get(3)) // 4
}

IndexOutOfBoundsException

get메서드와 set메서드를 사용할 때, index를 배열의 범위를 벗어나게 지정하면 IndexOutOfBoundsException이 발생합니다. 예외가 발생하지 않도록 주의하여 인자를 설정하거나 사용자 입력을 받아서 인자를 처리하게 된다면 예외 로직을 작성하도록 합시다.

size 프로퍼티

size 프로퍼티는 배열의 크기를 나타냅니다. val로 선언되어 변하지 않는 값입니다.

fun main() {
	val array: Array<Int> = Array(5) { idx: Int -> idx * idx }
    
    println(array.size) // 5
}

iterator 메서드

iterator 메서드는 배열 내부 요소를 순회할 수 있는 Iterator 객체를 반환합니다.

public interface Iterator<out T> {
    public operator fun next(): T

    public operator fun hasNext(): Boolean
}

Iterator의 hasNext 메서드를 사용하면 다음 요소가 존재하는지 여부를 판단할 수 있고 next메서드를 사용하면 다음 요소를 가져올 수 있습니다.

fun main() {
    val array: Array<Int> = Array(5) { idx: Int -> idx * idx }
    val iterator = array.iterator()
    
        while (iterator.hasNext()) {
        println(iterator.next())
    }
}
   /* [출력]
     * 0
     * 1
     * 4
     * 9
     * 16
     */

아래 예제처럼 for문을 사용하여 배열을 순회해본 경험이 있으실겁니다.

fun main() {
	val array: Array<Int> = Array(5) { idx: Int -> idx * idx }

	for (item in array) {
    	println(item)
    }
}
    /* [출력]
     * 0
     * 1
     * 4
     * 9
     * 16
     */

for문에서 사용하는 in 연산자는 iterator 연산자 오버로딩이 존재해야만 사용 가능합니다.
Array 클래스의 iterator에 operator 키워드가 붙어있기 때문에 in 연산자를 사용하여 요소를 순회할 수 있는것입니다.

range도 iterator를 가지고 있다!

우리가 for문에서 자주 사용하는 1..10 같은 IntRange와 같은 Range에도 iterator가 존재합니다.
IntRange는 IntProgression 클래스를 상속받습니다. IntProgression 클래스는 IntProgressionIterator를 반환하는 iterator() 메서드를 가지고 있습니다.
for문에서 IntRange를 사용하면 내부적으로 IntProgressionIterator에 정의된 동작에 따라 IntRange를 순회하게 됩니다.

출처

코틀린 공식문서

profile
수신제가치국평천하

0개의 댓글

관련 채용 정보