본문 바로가기

Language/Kotlin

코틀린[Kotlin] 컬렉션(Collections) 알아보기 (List, Map, Set ...)

이번에는 코틀린의 컬렉션에 대해서 알아보겠습니다.

컬렉션에는 일반적으로 동일한 타입의 여러 객체를 담을 때 사용합니다. 예를 들어, 한 부서의 모든 개발자의 평균 연령을 계산하는 데 사용할 수 있는 컬렉션을 구성할 수 있습니다.

다음 컬렉션 타입들이 Kotlin과 관련이 있습니다.

 

collection 다이어그램

List

리스트는 위치를 반영하는 정수인 인덱스로 데이터에 접근할 수 있는 순서가 있는 컬렉션입니다. 데이터는 리스트에서 두 번 이상 나타날 수 있습니다. 리스트의 예는 전화번호입니다. 전화번호 부는 번호들의 그룹이고, 번호들의 순서가 중요하며, 번호가 반복될 수 있습니다.

 

Kotlin에서 리스트는 변경 가능할 수 있거나(MutableList) 읽기 전용(List)일 수 있습니다. 리스트 생성을 위해 읽기 전용 리스트에는 표준 라이브러리 함수 listOf()를 사용하고 변경 가능한 리스트에는 mutableListOf()를 사용합니다. 원치 않는 수정을 방지하려면 변경 가능한 목록을 List로 캐스팅하여 읽기 전용의 리스트를 얻으면 됩니다. 

val systemUsers: MutableList<Int> = mutableListOf(1, 2, 3)      
val sudoers: List<Int> = systemUsers                             

fun addSystemUser(newUser: Int) {                                 
    systemUsers.add(newUser)                      
}

fun getSysSudoers(): List<Int> {                                  
    return sudoers
}

fun main() {
    addSystemUser(4)                                              
    println("Tot sudoers: ${getSysSudoers().size}")               
    getSysSudoers().forEach {                                    
        i -> println("Some useful info on user $i")
    }
    // getSysSudoers().add(5) <- Error!                          
}

위의 예시에서 MutableList에 업데이트가 가능하고 List에는 가능하지 않다는 것을 확인할 수 있습니다.

 

Set

Set은 중복을 지원하지 않는 정렬되지 않은 컬렉션입니다. Set을 생성하기 위한 setOf()mutableSetOf() 함수가 있습니다.

val openIssues: MutableSet<String> = mutableSetOf("uniqueDescr1", "uniqueDescr2", "uniqueDescr3") 

fun addIssue(uniqueDesc: String): Boolean {                                                       
    return openIssues.add(uniqueDesc)                                                            
}

fun getStatusLog(isAdded: Boolean): String {                                                       
    return if (isAdded) "registered correctly." else "marked as duplicate and rejected."         
}

fun main() {
    val aNewIssue: String = "uniqueDescr4"
    val anIssueAlreadyIn: String = "uniqueDescr2" 

    println("Issue $aNewIssue ${getStatusLog(addIssue(aNewIssue))}")                 // 1  
    println("Issue $anIssueAlreadyIn ${getStatusLog(addIssue(anIssueAlreadyIn))}")   // 2  
}

 

  1. 새로운 요소를 MutableSet에 추가하는 상황으로 성공적으로 수행됩니다.
  2. 중복된 요소를("uniqueDescr2") MutableSet에 추가하는 상황으로 에러가 발생합니다.

 

Map

맵은 각 키가 고유하고 해당 값을 검색하는 데 사용되는 키/값 쌍의 모음입니다. 맵을 생성하기 위해 mapOf()mutableMapOf() 함수가 있습니다. to infix 함수를 사용하면 초기화를 더 직관적이게 할 수 있습니다.

const val POINTS: Int = 15
val accounts: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)
val accountsReportMap: Map<Int, Int> = accounts                                  

fun updatePoint(accountId: Int) {
    if (accounts.containsKey(accountId)) {                                  
        println("Updating $accountId...")                                               
        accounts[accountId] = accounts.getValue(accountId) + POINTS  
    } else {
        println("Error: Trying to update a non-existing account (id: $accountId)")
    } 
}

fun accountsReport() {
    println("report:")
    accountsReportMap.forEach {                                                        
        k, v -> println("ID $k: credit $v")
    }
}

fun main() {
    accountsReport()                                                                    
    updatePoint(1)                                                               
    updatePoint(1)                                                               
    updatePoint(5)                                                               
    accountsReport()                                                                    
}