배열
배열은 고정된 갯수의 서로 같은 타입의 값들을 저장하는데 쓰이는 자료 구조입니다.
Kotlin 에서 가장 흔한 배열 타입은 오브젝트 타입의 배열로, Array
클래스에 의해 표현됩니다.
오브젝트 타입의 배열에 원시 값을 사용하면, 그 원시 값들 각각이 오브젝트로 포장되기 때문에 성능 이슈가 발생합니다. 이러한 포장 오버헤드를 방지하려면, 원시 타입 배열을 사용하세요.
언제 배열을 써야하는가
Kotlin 에서는, 만족시켜야 하는 어떤 저수준의 필요사항이 있을 때 사용합니다. 예를 들어, 일반적인 어플리케이션 이상의 성능 요구 사항이 있거나, 커스터마이징된 자료 구조를 만들 때 등이 있습니다. 이러한 제한 사항이 없다면, 컬렉션을 대신 사용하세요.
컬랙션은 배열에 비해 아래와 같은 이점들이 있습니다:
- 컬렉션은 읽기 전용이 될 수 있으며, 여러분에게 더 세세한 조절과 명확한 의도를 가진 본격적인 코드를 작성하도록 해줍니다.
- 컬렉션은 요소를 추가하거나 제거하기 쉽습니다. 배열은 크기가 고정되는 것과 비교되는 사항이죠. 배열에서 요소를 추가하거나 제거하는 유일한 방법은, 매번 비효율적으로 새로운 배열을 만드는 것 뿐입니다:
1var riversArray = arrayOf("Nile", "Amazon", "Yangtze") 2 3// Using the += assignment operation creates a new riversArray, 4// copies over the original elements and adds "Mississippi" 5riversArray += "Mississippi" 6println(riversArray.joinToString()) 7// Nile, Amazon, Yangtze, Mississippi 8
- 컬렉션은 동일성 비교 연산자(
==
)를 사용하여 그들의 내용이 같은지 구조적 동일성을 비교할 수 있습니다. 하지만 배열에서는 같은 연산자가 참조적 동일성을 비교하기 때문에 이 방식을 사용할 수 없고 배열의 비교 문단에서 서술하는 특수한 함수를 사용해야합니다.
컬렉션에 대한 더 자세한 사항은 컬렉션 훑어보기 문서를 확인해보세요.
배열 만들기
Kotlin 에서 배열을 만드려면, 아래 방법 중 하나를 사용할 수 있습니다:
arrayOf()
,arrayOfNulls()
,emptyArray()
와 같은 함수Array
생성자
아래의 예제는 arrayOf()
를 사용하여 각 요소를 전달합니다:
1// Creates an array with values [1, 2, 3]
2val simpleArray = arrayOf(1, 2, 3)
3println(simpleArray.joinToString())
4// 1, 2, 3
5
아래의 예제는 arrayOfNulls()
를 사용하여 주어진 길이의 null
로 채워진 배열을 생성합니다.
1// Creates an array with values [null, null, null]
2val nullArray: Array<Int?> = arrayOfNulls(3)
3println(nullArray.joinToString())
4// null, null, null
5
아래의 예제는 emptyArray()
를 사용하여 빈 배열을 생성합니다:
1var exampleArray = emptyArray<String>()
2
빈 배열의 타입은 Kotlin 의 타입 유추에 의거해 할당 연산자의 왼쪽과 오른쪽 모두에 사용할 수 있습니다.
예를 들면 아래와 같습니다.
1var exampleArray = emptyArray<String>() 2var exampleArray: Array<String> = emptyArray() 3
Array
생성자는 배열의 크기와 인덱스에 따라 값을 산출하는 함수를 인수로 받습니다:
1// Creates an Array<Int> that initializes with zeros [0, 0, 0]
2val initArray = Array<Int>(3) { 0 }
3println(initArray.joinToString())
4// 0, 0, 0
5
6// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
7val asc = Array(5) { i -> (i * i).toString() }
8asc.forEach { print(it) }
9// 014916
10
대부분의 프로그래밍 언어와 동일하게, 인덱스는 0부터 시작합니다.
중첩된 배열
배열은 다차원 배열을 만들기 위해 서로 간에 중첩될 수도 있습니다:
1// Creates a two-dimensional array
2val twoDArray = Array(2) { Array<Int>(2) { 0 } }
3println(twoDArray.contentDeepToString())
4// [[0, 0], [0, 0]]
5
6// Creates a three-dimensional array
7val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } }
8println(threeDArray.contentDeepToString())
9// [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
10
안쪽의 중첩된 배열들은 서로 같은 타입이나 길이를 가지지 않아도 됩니다.
예제에는 나타나있지 않지만, arrayOf()
등의 배열을 만드는 함수를 사용해도 중첩된 배열을 만들 수 있습니다.
요소에의 접근과 수정
배열은 항상 변경 가능합니다. 배열의 요소에 접근하고 수정하려면, 인덱스 접근 연산자 []
를 사용합니다:
1val simpleArray = arrayOf(1, 2, 3)
2val twoDArray = Array(2) { Array<Int>(2) { 0 } }
3
4// Accesses the element and modifies it
5simpleArray[0] = 10
6twoDArray[0][0] = 2
7
8// Prints the modified element
9println(simpleArray[0].toString()) // 10
10println(twoDArray[0][0].toString()) // 2
11
Kotlin 의 배열 타입은 불변합니다.
이는 Kotlin 이 Array<String>
을 Array<Any>
에 할당하는 것을 허용하지 않는다는 것을 의미합니다.
이럴 때는 Array<out Any>
를 사용할 수 있으며, 이와 관련된 자세한 사항은 타입 투사 문서를 확인해보세요.
배열과의 작업
Kotlin 에서는, 배열을 정해지지 않은 갯수의 매개변수를 가지는 함수에 인수로 전달하거나, 물론이지만 그 자체에 어떠한 작업도 할 수 있습니다. 예를 들면, 배열들을 비교하거나 그 내용을 변경하거나, 배열을 컬렉션으로 변환하는 등이 있습니다.
정해지지 않은 갯수의 인수를 함수에 전달하기
Kotlin 에서는 정해지지 않은 수의 인수를 vararg
매개변수에 전달할 수 있습니다.
이는 메시지를 포매팅하거나 SQL 쿼리를 작성할 때 등 구현 측에서 몇 개의 인수가 올지 알 수 없을 때 유용합니다.
정해지지 않은 수의 인수들을 가진 배열을 함수에 전달하려면, 펼치기 연산자(*
)를 사용합니다.
펼치기 연산자는 배열의 각 요소를 독립적인 인수로 함수에 전달합니다:
1fun main() {
2 val lettersArray = arrayOf("c", "d")
3 printAllStrings("a", "b", *lettersArray)
4 // abcd
5}
6
7fun printAllStrings(vararg strings: String) {
8 for (string in strings) {
9 print(string)
10 }
11}
12
더 많은 정보는 정해지지 않은 갯수의 매개변수 (varargs) 문단을 확인해보세요.
배열의 비교
배열이 서로 같은 요소를 같은 순서로 가지고 있는지 확인하려면, .contentEquals()
나 .contentDeepEquals()
를 사용합니다:
1val simpleArray = arrayOf(1, 2, 3)
2val anotherArray = arrayOf(1, 2, 3)
3
4// Compares contents of arrays
5println(simpleArray.contentEquals(anotherArray))
6// true
7
8// Using infix notation, compares contents of arrays after an element
9// is changed
10simpleArray[0] = 10
11println(simpleArray contentEquals anotherArray)
12// false
13
배열의 내용을 비교하기 위해 동일성 판단 연산자(
==
,!=
)를 사용하면 안됩니다. 이 연산자들은 두 피연산자가 서로 같은 오브젝트를 가리키는지 비교하는 참조적 동일성을 판단합니다.Kotlin 의 배열이 왜 이렇게 동작하는지에 대해서는, 이 블로그의 포스트를 살펴보세요.
배열의 변환
Kotlin 에는 배열을 변환하기 위한 많은 쓸만한 함수들이 있습니다. 이 문서에서는 몇몇 가지만 소개하지만, 이들로 국한되지 않습니다. 전체 목록을 확인하려면, API 레퍼런스를 확인해보세요.
Sum
모든 배열 요소의 합을 구하려면, .sum()
함수를 사용합니다:
1val sumArray = arrayOf(1, 2, 3)
2
3// Sums array elements
4println(sumArray.sum())
5// 6
6
.sum()
함수는 배열이 숫자형 데이터 타입을 요소로 가질 때만 사용 가능합니다. 예를 들면Int
등이 있습니다.
Shuffle
배열 안의 데이터를 랜덤한 순서로 섞으려면, .shuffle()
함수를 사용합니다:
1val simpleArray = arrayOf(1, 2, 3)
2
3// Shuffles elements [3, 2, 1]
4simpleArray.shuffle()
5println(simpleArray.joinToString())
6
7// Shuffles elements again [2, 3, 1]
8simpleArray.shuffle()
9println(simpleArray.joinToString())
10
컬렉션으로의 변환
어떤 건 배열을 쓰고 어떤 건 컬렉션을 쓰는 서로 다른 API들로 작업중이라면, 배열을 컬렉션 등으로 변환할 수 있습니다:
리스트나 집합으로의 변환
배열을 List
나 Set
으로 변환하려면, .toList()
나 .toSet()
를 사용하세요.
1val simpleArray = arrayOf("a", "b", "c", "c")
2
3// Converts to a Set
4println(simpleArray.toSet())
5// [a, b, c]
6
7// Converts to a List
8println(simpleArray.toList())
9// [a, b, c, c]
10
Map 으로의 변환
배열을 Map
으로 변환하려면, .toMap()
함수를 사용하세요.
단, Pair<K, V>
타입을 요소로 가지는 배열만이 Map
으로 변환될 수 있습니다. Pair
인스턴스의 첫 값(first
)이 Map 의 키가 되고, 두 번째 값(second
)이 Map 의 값이 됩니다.
이 예제에서는 Pair
인스턴스를 만들기 위해 to
함수를 infix 표기법으로 호출했습니다.
1val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)
2
3// Converts to a Map
4// The keys are fruits and the values are their number of calories
5// Note how keys must be unique, so the latest value of "apple"
6// overwrites the first
7println(pairArray.toMap())
8// {apple=140, banana=150, cherry=90}
9
원시 타입 배열
Array
클래스를 통해 원시 타입의 값들을 요소로 가지게 하면, 모든 값들이 그에 해당하는 Java 클래스의 오브젝트로 포장됩니다.
대안으로, 미리 준비된 원시타입 배열들을 사용해 원시 값들을 오버헤드 없이 배열에 저장할 수 있습니다:
원시 타입 배열 | Java 의 동일한 데이터타입 |
---|---|
BooleanArray | boolean[] |
ByteArray | byte[] |
CharArray | char[] |
DoubleArray | double[] |
FloatArray | float[] |
IntArray | int[] |
LongArray | long[] |
ShortArray | short[] |
이 클래스들은 Array
클래스와 상속관계에 있지 않지만, Array
가 가지는 함수들을 모두 그대로 가지고 있습니다.
이 예제는 IntArray
클래스의 인스턴스를 만듭니다:
1// Creates an array of Int of size 5 with the values initialized to zero
2val exampleArray = IntArray(5)
3println(exampleArray.joinToString())
4// 0, 0, 0, 0, 0
5
원시 타입의 배열을 오브젝트 타입의 배열로 변환하려면,
.toTypedArray()
함수를 사용합니다.오브젝트 타입의 배열을 원시 타입의 배열로 변환하려면,
.toBooleanArray()
,.toByteArray()
,.toCharArray()
등을 사용합니다.
더 알아보기
- 대부분의 경우에서 컬렉션을 사용하기를 권장하는 이유에 대해 알아보려면, 컬렉션 훑어보기 문서를 살펴보세요.
- 다른 기본 타입들에 대해 살펴보세요.
- 만약 당신이 Java 개발자라면, Collection 에 대한 Java 에서 Kotlin 으로의 마이그레이션 가이드 를 읽어보세요.
이 페이지가 도움이 되셨다면, 원문 페이지에 방문해 엄지척을 해주세요!