관리 메뉴

나만을 위한 블로그

[Kotlin] 코틀린의 컬렉션(List, Map, Set) 본문

개인 공부/Kotlin

[Kotlin] 코틀린의 컬렉션(List, Map, Set)

참깨빵위에참깨빵 2020. 10. 17. 19:31
728x90
반응형

코틀린도 프로그래밍 언어니까 리스트나 맵 따위의 컬렉션 시리즈도 제공하고 있다.

그런데 사용법이 조금 특이하다. 자바는 대충 ArrayList 객체화 때리고 안에 값 add 해서 지지고 볶으면 그만인데, 코틀린에선 안의 값을 수정할 수 있는 컬렉션과 수정할 수 없는 컬렉션으로 나눠서 만들어놓았다.

val, var의 차이를 컬렉션에서도 구현해놓은 것 같다.

시작하기 전에 코틀린의 컬렉션이 가진 상속 구조를 그림으로 표현한 것부터 간단하게 보고 넘어가자.

 

앞에 Mutable만 없었다면 자바에서 자주 보이는 것들이다.

그럼 List부터 어떤 식으로 만드는지 확인하자.

 

  • List

List는 "목록, 명단, (특정 순서로) 열거하다"란 뜻이 있는 단어다.

그래서 List에는 하나 이상의 값들을 넣을 수 있다. 코틀린에서 이 리스트란 놈을 만들려면 어떻게 해야 할까?

먼저 아래 코드를 입력한다.

 

fun main(args: Array<String>)
{
    val number = listOf(1, 2, 3)
    for (i in 0..number.size - 1)
    {
        println(number.get(i))
    }
}

 

1부터 3까지 숫자를 리스트에 넣은 다음 val 변수에 넣고, 이걸 for문으로 돌려서 하나씩 print하는 간단한 코드다. for문 안에서 -1을 한 이유는 저 부분을 지워보면 바로 알 수 있으니 생략한다.

listOf()는 수정 불가능한 리스트를 만들어주는 메서드다. listOf()의 lis까지만 치고 자동완성시킬 경우 listOf<>() 형태의 코드가 나타난다. 중간에 낀 제네릭은 없어도 되니 지워도 문제없다.

실행 시 아래로 1부터 3까지 나열된다.

그런데 여기서 number에 다른 값들을 넣어보면 어떻게 될까?

애초에 넣을 수가 없다. listOf()로 리스트를 만든 경우 add() 자체를 쓸 수 없어 시도조차 할 수 없다.

그럼 이제 수정 가능한 리스트를 만들어보자.

 

fun main(args: Array<String>)
{
    val number = mutableListOf(1, 2, 3)
    number.add(100)
    for (i in 0..number.size - 1)
    {
        println(number.get(i))
    }
}

 

mutableListOf()를 사용하면 수정 가능한 리스트를 만들 수 있다. 바로 밑줄의 number.add(100)을 보면 알겠지만 저렇게 하면 3 뒤에 100이란 숫자가 들어간다.

 

 

그런데 난 지금까지 number를 val로 선언했다. 그런데도 number라는 리스트에 100이란 값을 넣을 수 있었다. val을 쓰면 재할당이 불가능한데, 이게 어떻게 가능한 일일까?

코틀린 공식 홈페이지를 찾아보면 아래와 같은 설명과 예시가 있다.

 

- Note that altering a mutable collection doesn't require it to be a var: write operations modify the same mutable collection object, so the reference doesn't change. Although, if you try to reassign a val collection, you'll get a compilation error.

 

- 변경 가능한 컬렉션을 변경할 때 var일 필요는 없습니다. 쓰기 작업은 동일한 변경 가능한 컬렉션 객체를 수정하므로 참조가 변경되지 않습니다. 그러나 val 컬렉션을 다시 할당하려고하면 컴파일 오류가 발생합니다.

 

조금만 생각해보면 알겠지만, 컬렉션은 변수가 아니라 객체를 만들어 참조하는 식으로 사용한다.

val은 변수값이 안 바뀌게 하는 것이지 객체값이 안 바뀌게 하는 건 아니기 때문에, val을 쓰더라도 컬렉션 객체를 참조해서 add()나 remove()를 사용할 수 있는 것이다.

그러니 컬렉션을 쓸 때는 val이든 var이든 편한 대로 쓰면 되고, 나중에 수정할 것인지 아닌지에 따라 메서드를 가려서 쓰면 된다.

 

  • Map

Map은 키밸류 형태로 key에 value를 매핑하는 객체다. 나중에 값을 검색할 때 key값으로 검색해 찾을 수 있다. 코틀린에서도 별다를 건 없다.

만드는 방법은 리스트와 똑같이 mapOf()를 쓰거나 mutableMapOf()를 써서 만들면 된다.

이 형태는 코틀린의 컬렉션 중 어떤 것을 만들더라도 동일하게 적용된다. for문을 쓰는 방식만 조금 바뀐다.

 

fun main(args: Array<String>)
{
    val number = mapOf(1 to "google", 2 to "tistory", 3 to "medium")
    for (i in number.keys)
    {
        println(number.get(i))
    }
    println("==========================================")
    for (i in number)
    {
        println(number)
    }
}

정수 to "문자열" 방식으로 썼는데 당연히 "문자열" to 정수 방식으로 써도 된다.

===의 위와 아래에 있는 for문의 형태를 잘 보고 결과가 각각 어떻게 출력되는지 확인하자.

 

 

그리고 코틀린은 Map에서 +와 -를 써서 키를 넣고 뺄 수 있다. value를 넣고 뺄 수는 없다.

 

fun main(args: Array<String>)
{
    val number = mapOf(1 to "google", 2 to "tistory", 3 to "medium")
    for (i in number.keys)
    {
        println(number.get(i))
    }
    println("==========================================")
    val other_number = number - 3
    for (i in other_number.keys)
    {
        println(other_number.get(i))
    }
}

역시 ===의 위, 아래 차이를 확인하자.

 

  • Set

set은 List와 비슷한 컬렉션이지만 중복을 허용하지 않는 특징이 있다.

 

fun main(args: Array<String>)
{
    val number = setOf(3, 3, 1, 2)
    println(number)
}

 

3이 두 번 들어갔는데 출력하니 하나의 3만 출력되는 걸 볼 수 있다.

마찬가지로 mutableSetOf()를 사용하면 수정 가능한 set를 만들 수 있다. 위의 set는 수정 불가능한 set이다.

add()로 3을 넣더라도 출력하지 않는 걸 볼 수 있다.

 

fun main(args: Array<String>)
{
    val number = mutableSetOf(3, 3, 1, 2)
    number.add(3)
    number.add(4)
    println(number)
}

반응형
Comments