배열 (Array)란, 여러개의 데이터를 효율적으로 처리하기 위해 고안된 자료구조입니다.
원소들이 연속적으로 나열되어 있는 형태이며,
한 번 선언된 배열의 크기를 바꾸는 것은 불가능합니다.
굉장히 자주 쓰이는 기본적인 자료구조인데요.
자바를 자주 쓰셨던 분들이라면 int[] arr = new int[3]; 과 같은 형태로 많이 쓰셨을텐데,
코틀린에서는 어떻게 배열을 생성하고 사용할까요?
코틀린의 배열 생성
var arr = arrayOf(1,2,3) // 0번째 인덱스 -> 1, 1번째 인덱스 -> 2, 2번째 인덱스 -> 3
println(arr[1])
// 출력
2
코틀린에서 배열은 위와 같이 arrayOf(원소 1, 원소 2, 원소 3, ... )으로 생성할 수 있습니다.
val intArr = intArrayOf(1,2,3,4,5) // IntArray
val longArr = longArrayOf(1L,2L,3L,4L) // LongArray
val boolArr = booleanArrayOf(false, true, false, true) // BooleanArray
혹은 위와 같이, 팩토리 메소드를 통해 특정 타입의 배열을 선언할 수도 있습니다.
arrayOf를 사용해 배열을 생성할 경우, 자동으로 타입을 추론하여 그에 맞는 배열을 생성하므로,
저는 arrayOf를 주로 씁니다.
생성자를 이용한 배열 생성
val arr = Array<Int>(3) { it } // 0, 1, 2
println(arr[0])
println(arr[1])
println(arr[2])
// 출력
0
1
2
============================
val arr2 = Array<Int>(3) { it * 2 } // 0, 2, 4
println(arr[0])
println(arr[1])
println(arr[2])
// 출력
0
2
4
============================
val arr2 = Array<Int>(3) { 0 } // 0, 0, 0
println(arr[0])
println(arr[1])
println(arr[2])
// 출력
0
0
0
위와 같이 생성자를 사용해 배열을 선언할 수도 있습니다.
이는 Array<Type> (n) 뒤에있는 { } 안에 람다식을 넣음으로써 생성할 수 있는데
it이 0 부터 n(배열 길이)까지 반복되며, 그에 맞는 값으로 원소가 생성됩니다.
람다식 | idx = 0 | idx = 1 | idx = 2 | idx = 3 | idx = 4 |
{ it } | 0 | 1 | 2 | 3 | 4 |
{ 0 } | 0 | 0 | 0 | 0 | 0 |
{ it * 2 } | 0 | 2 | 4 | 6 | 8 |
{ it + 5 } | 5 | 6 | 7 | 8 | 9 |
{ it * it } | 0 | 1 | 4 | 9 | 16 |
val arr = Array<String>(3) { readLine() }
println(arr[0])
println(arr[1])
println(arr[2])
// 입력
>> 코틀린은
>> 사랑입니다.
>> 사실 아님....
// 출력
>> 코틀린은
>> 사랑입니다.
>> 사실 아님...
저는 코딩 테스트에서 readLine()을 이용해 값을 입력받을 때,
그냥 람다식 부분에 readLine()을 넣으면, 한 줄씩 값을 입력받아,
배열 생성 및 값 초기화까지 한 번에 처리할 수 있기 때문에 위와 같은 방법을 애용합니다.
코틀린과 이차원 배열
자, 배열의 생성방법을 알아봤으니, 이번엔 이차원 배열의 생성방법도 알아볼까요?
val arr = Array(3) { Array(3) { 0 } }
val arr = arrayOf(arrayOf(0,1,2), arrayOf(3,4,5), arrayOf(6,7,8))
배열 안에 배열을 넣어 2차원 배열을 구현할 수 있었습니다.
녜???
2차원 배열의 선언 및 생성은 다소 당황스러웠습니다.
저는 코틀린의 깔끔한 문법이 굉장히 마음에 들었는데,
갑자기 자바의 int[][] arr = new int[3][3]; 이 그리워지기 시작했습니다.
그럼, 3차원 배열은요?
val arr = Array(3) { Array(3) { Array(3) { 0 } } }
이쯤되면 다들 예상했을거라 싶습니다.
배열 안에 배열 안에 배열을 넣음으로써 생성할 수 있습니다.
흠... 다차원 배열이 다소 생소하긴 하나, 익숙해지면 꽤 쓸만합니다.
특히, 람다식을 사용한 배열 생성 같은 경우는
제 마음대로 배열을 생성 + 초기화 할 수 있어, 꽤 맘에 드는 요소입니다.
부록. Array <Int> vs IntArray?
코틀린의 배열을 쓰다보면 물음표를 갖게 되는 순간이 있습니다.
바로 두 가지 배열 타입이 있다는 것인데요.
Array<Int> vs IntArray
Array<Long> vs LongArray
Array<Char> vs CharArray
Array<Boolean> vs BooleanArray
Array<Double> vs DoubleArray 등등 입니다.
Array<Int>와 IntArray는 Int형 배열이라는 점에서 동일합니다. 사용법도 별 차이가 없고요.
그럼, 이 두 타입은 무슨 차이가 있는 걸까요?
이는 Primmitive 타입과 관련이 있습니다.
코틀린에서는 모든게 객체입니다. Int, Double, Boolean, Char등 Primmitive 타입까지 전부 다.
자바의 경우는 int는 객체가 아닙니다.
int를 객체형으로 쓰고 싶을 땐, Integer 타입을 씁니다. 이러한 타입을 wrapper class라고 합니다.
IntArray, DoubleArray, LongArray와 같은 형태는 자바의 원시 타입 객체와 대응됩니다.
Array<Type>은 Int, Long, Double 등 Primmitive 타입 말고도 다른 타입의 배열이 생성이 가능하나,
IntArray, DoubleArray 등은 오직 Primmitive 타입만 지원합니다.
이들은 Array<Type>보다 속도 측면에서 더 나은 퍼포먼스를 보입니다만,
그렇게 드라마틱한 차이는 없으니, 맘에 드는 걸 쓰면 됩니다.
Array<Int> <--> IntArray 변환은
val arr = Array<Int>(3) {it}
val arr2 = arr.toIntArray() // Array<Int> -> IntArray
val arr3 = intArrayOf(0,1,2)
val arr4 = arr3.toTypedArray() // IntArray -> Array<Int>
위와 같이 간편하게 할 수 있습니다.
부록. 배열 관련 기능
arr.size
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(arr.size)
// 출력
>>> 10
arr.size는 배열의 길이를 반환하는 메소드입니다.
arr.contentToString()
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(arr.contentToString())
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
contentToString()은 배열 내 원소를 문자열로 반환하는 메소드입니다.
프로그래머스에서 코딩 테스트를 본 적이 있었는데,
외부 IDE를 사용하지 못해 println()을 사용해 디버깅을 해야 했었습니다.
그 때, 매우 유용하게 사용했던 것 같네요.
arr.sum()
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(arr.sum())
// 출력
>>> 55
배열 내 원소의 합을 return 하는 arr.sum() 입니다.
당연하게도, 숫자 타입(Int, Double, Long, Short, Float, Byte)만 지원합니다.
arr.average()
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(arr.average())
// 출력
>>> 5.5
arr.average()는 배열 내 원소들의 평균을 반환합니다.
숫자 타입(Int, Double, Long, Short, Float, Byte)만 지원합니다.
arr.reverse()
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
arr.reverse()
println(arr.contentToString())
// 출력
>>> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
arr.reverse()를 통해 배열 내 원소의 값을 뒤집을 수 있습니다.
반환값을 통해 reverse된 배열을 return 해주는 것이 아니라, 배열 내 원소를 뒤집습니다.
반환값은 Unit(void) 입니다.
arr.reversedArray()
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val arr2 = arr.reversedArray()
println(arr2.contentToString())
// 출력
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
reversedArray()는 내용이 뒤집어진 배열을 return 해주는 메소드입니다.
원본 배열은 그대로입니다.
arr.sort(), arr.sortedDescending()
val arr = arrayOf(1, 2, 5, 3, 2, 1, 2, 53645, 234, 7, 8, 9, 10)
arr.sort()
println(arr.contentToString())
arr.sortDescending()
println(arr.contentToString())
// 출력
>>> [1, 1, 2, 2, 2, 3, 5, 7, 8, 9, 10, 234, 53645]
[53645, 234, 10, 9, 8, 7, 5, 3, 2, 2, 2, 1, 1]
arr.sort()를 통해 배열 내 원소를 정렬할 수 있습니다.
기본적으로 오름차순으로 정렬되며,
내림차순으로 정렬하고 싶을 땐 sortDescending()을 사용합니다.
코딩테스트를 할 때 아주 많이 쓰이는 메소드 중 하나이며,
수많은 개발자들의 연구와 꼼수가 집약되어,
매우 빠르게 작동합니다.
arr.sortedArray()
val arr = arrayOf(1, 2, 5, 3, 2, 1, 2, 53645, 234, 7, 8, 9, 10)
val arr2 = arr.sortedArray()
println(arr.contentToString())
println(arr2.contentToString())
// 출력
>>> [1, 2, 5, 3, 2, 1, 2, 53645, 234, 7, 8, 9, 10]
[1, 1, 2, 2, 2, 3, 5, 7, 8, 9, 10, 234, 53645]
sortedArray()는 정렬된 배열을 return 해주는 메소드입니다.
원본 배열에는 영향을 주지 않습니다.
arr.max() / arr.min()
val arr = arrayOf(1, 2, 5, 3, 2, 1, 2, 53645, 234, 7, 8, 9, 10)
println(arr.max())
println(arr.min())
// 출력
>>> 53645
1
max() / min() 은 배열 내 가장 큰 / 가장 작은 원소를 반환하는 메소드입니다.
arr1 + arr2
val arr1 = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val arr2 = arrayOf(7, 8, 9, 10)
val arr3 = arr1 + arr2
println(arr3.contentToString())
// 출력
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 7, 8, 9, 10]
‘+’ 키워드를 사용해 두 배열을 이어붙일 수 있습니다.
그 외. 코틀린 공식 문서
이 외에도 배열의 기능은 매우 다양하여 다 정리하지 못했습니다.
더 많은 기능이 궁금하시다면, 개발자들의 영원한 친구인 공식 문서를 참고해주세요!
https://kotlinlang.org/docs/home.html
'코틀린 파헤치기 > 1부. 코틀린 기초' 카테고리의 다른 글
[코파기 1부] 9. 코틀린과 반복문 (1) : for, while, do-while, repeat, forEach (2) | 2023.03.15 |
---|---|
[코파기 1부] 8. 코틀린과 리스트 (List) (0) | 2023.03.15 |
[코파기 1부] 6. 코틀린과 null (.? !!. ?:) (0) | 2023.03.14 |
[코파기 1부] 5. 코틀린과 조건문. 그리고 표현식 (0) | 2023.03.14 |
[코파기 1부] 4. 코틀린과 연산자 (0) | 2023.03.14 |