본문 바로가기
개발언어/Kotlin : 코틀린

코틀린 익히기 10 - 배열

by 개발자D 2023. 10. 1.

배열

배열 Array

배열

자바의 배열은 같은 타입의 여러 데이터를 하나로 묶어 보관하는 구조였습니다. 하지만, 코틀린의 배열은 여러 가지 타입의 데이터를 묶을 수 있습니다. 데이터들은 Index라는 번호를 통해 구분됩니다.  

 

배열 생성

배열을 생성하는 여러 가지 방법이 있습니다. 배열은 한 번 생성되고 나면 그 길이를 수정할 수 없습니다.

 

arrayOf(), arrayOfNulls<>()

arrayOf()를 사용하면 배열을 직접 입력해 생성할 수 있습니다. arrayOfNulls<>()를 사용하면 null로 구성된 배열을 만들 수 있습니다.

val|var 배열이름 = arrayOf(배열)

val|var 배열이름 = arrayOfNulls<배열에 들어갈 요소의 자료형>(사이즈)

 

val numbers = arrayOf(1, 2, 3, 4)
// [1, 2, 3, 4]

var countries = arrayOf("한국", "호주", "미국")
// ["한국", "호주", "미국"]

val nulls = arrayOfNulls<Int>(3)
// [null, null, null]

Array()

val|var 배열이름 = Array(크기, 표현식)

 

val arr = Array(5, {i -> i * 5}) 
// [0, 5, 10, 15, 20] 

var arr = Array(1000, {0})
// [0, 0, 0, 0, 0, ...., 0]

 

❓ 표현식이 뭔가요?

- 표현식이란 결과가 하나의 값으로 표현되는 문장을 말합니다. 

 

배열 요소의 자료형을 고정하는 방법

코틀린의 배열은 여러 자료형을 동시에 저장할 수 있다고 설명드렸습니다. 그렇다면 한 가지 자료형으로 고정하고 싶을 땐

어떻게 해야 할까요? 그럴 땐 arrayOf() 메서드에 제네릭<>을 사용하거나 자료형 이름 + ArrayOf() 형태의 메서드를 사용하면 됩니다. 

val intArray = arrayOf<Int>(1, 2, 3)
val intArray = intArrayOf(1, 2, 3)

 


배열 길이

배열 길이는 자바와 달리 length가 아닌 배열이름.size로 확인할 수 있습니다. 배열 길이의 최소 크기는 0이며, 최대 크기는 int형의 최댓값(약 21억)과 같습니다.

 

배열의 출력

Arrays.toString(배열) 이나 배열.contentToString() 을 사용하여 출력합니다.

[첫 번째 요소, 두 번째 요소, …, 마지막요소]

 

import java.util.*

fun main() {
    var arr = arrayOf(1, 2, 3)

    println(Arrays.toString(arr)) // [1, 2, 3]
    println(arr.contentToString()) // [1, 2, 3]
}

 

다차원 배열의 경우 Arrays .deepToString(배열) 이나 배열.contentDeepToString() 을 사용하여 출력합니다.

[[첫 번째 요소, 두 번째 요소, …, 마지막요소], [...], [...]]
import java.util.*

fun main() {
    var arr2 = arrayOf(arrayOf(1, 2, 3),arrayOf(4, 5, 6), arrayOf(7, 8, 9))

    println(Arrays.deepToString(arr2)) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    println(arr2.contentDeepToString()) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
}

 

자바와 달리 char 배열도 Arrays.toString() 이나 contentToString() 없이 출력할 경우 참조변숫값이 출력됩니다. 

 

배열 요소에 접근

배열의 인덱스를 사용하여 배열의 각 저장공간에 접근할 수 있습니다. 배열의 index는 0부터 시작한다는 사실을 기억하세요.

배열이름[인덱스번호]

 

다차원 배열의 경우 차원 수만큼 대괄호([])를 사용해 접근합니다.

예시 )
2차원 배열
배열이름[인덱스번호][인덱스번호]

 

혹은 게터(배열이름.get(인덱스번호))나 세터(배열이름.set(인덱스번호, 값))를 사용하는 방법도 있습니다.

 

배열 요소에 순환하여 접근

배열을 순환하는 여러 가지 방법이 있습니다. forEach()와 forEachIndexed()는 람다식을 사용하여 접근한 요소를 처리합니다.

 

forEach()

배열의 각 요소를 e로 받아 처리합니다.

arr.forEach { e -> print("$e") }

forEachIndexed()

배열의 각 인덱스는 i로 요소는 e로 받아 처리합니다.

arr.forEachIndexed {i, e -> println("arr[$i] = $e")}

iterator()

iterator() 메서드로 이터레이터를 만들어 순차적으로 요소에 접근할 수 있습니다.

hasNext() : 다음 요소가 있는지 확인하는 메서드입니다.

next() : 다음 요소에 접근하는 메서드입니다. 

val iterator: Iterator<Int> = arr.iterator()
while (iterator.hasNext()) {
	val e = iterator.next()
	print("$e")
}

 


배열의 주요 메서드

계산

arr.sum() // 배열의 합
arr.average() // 배열의 평균
arr.count() // 요소의 개수 (arr.size와 같습니다)

 

요소 / 인덱스 확인

arr.first() // 첫 요소
arr.last() // 마지막 요소
arr.indexOf(요소) // 요소의 인덱스 번호 반환
arr.contains(요소) // arr 배열에 요소가 있는지 확인

 

요소 추가 / 자르기

arr.plus(요소) // 배열에 요소를 추가하여 새로운 배열을 반환
arr.sliceArray(범위) // 배열의 범위를 잘라 새로운 배열을 반환

 

정렬

sort와 sortDescending는 fromIndex에서 toIndex - 1까지의 범위를 정렬합니다.

만약 fromIndex, toIndex를 생략할 경우 전체 요소를 정렬합니다.

// 기존 배열을 정렬
arr.sort(fromIndex, toIndex) // 오른차순
arr.sortDescending(fromIndex, toIndex) // 내림차순

// 새로운 배열을 반환
arr.sortedArray() // 오름차순
arr.sortedArrayDescending() // 내림차순

// 배열을 정렬해 List로 반환
arr.sorted()  // 오름차순
arr.sortedDescending() // 내림차순

// 표현식에 따라 기존 배열을 정렬
arr.sortBy { 표현식 } // 오름차순
arr.sortByDescending { 표현식 } // 내림차순

// 표현식에 따라 배열을 정렬해 List로 반환
arr.sortedBy { 표현식 }
arr.sortedByDescending { 표현식 }

 

필터링

조건에 일치하는 데이터를 골라 List로 반환합니다.

arr.filter { e -> e in 1..2 }

 

평탄화

평탄화는 다차원 배열을 단일 배열로 만드는 것을 의미합니다.

arr.flatten()

 


String 클래스

자바 쉽게 배우기 5 - 배열에서 설명한 String클래스의 메서드를 참고하시면 좋습니다.

 

StringBuilder / StringBuffer

기존의 String 자료형은 문자를 변경할 때마다 새로운 객체를 생성해 할당합니다. 문자 변경이 빈번하게 이뤄질 경우 메모리 낭비 문제가 발생하게 됩니다. 

 

이럴 땐 String이 아닌 StringBuilder나, StringBuffer를 사용합니다.

StringBuilder와 StringBuffer는 문자열이 사용할 공간을 좀 더 크게 잡아 문자를 변경할 수 있도록 합니다. 다만 String 보다 처리 속도가 느리다는 단점이 있습니다.

 

StringBuffer는 스레드에서 안정적으로 동작하지만 StringBuilder는 불안정합니다. 따라서 스레드 환경에서는 StringBuffer를 사용하는 것이 바람직합니다.

var s = StringBuilder("Hello") / StringBuffer("Hello")
s.append("Kotlin") // HelloKotlin
s.insert(11, "World") // HelloKotlinWorld
s.delete(5, 11) // HelloWorld

배열에 대해 간단하게 살펴보았습니다. 배열의 주요 메서드들은 자주 사용되니 외워두는 것이 좋습니다. 배열을 배웠으면 다음은?!?! 역시나 컬렉션이죠! 다음 글에서는 컬렉션 프레임워크에 대해 공부합니다.