Learn & Record

Kotlin (컬렉션, 리스트 List, 셋 Set, 맵 Map) 본문

Dev/Kotlin

Kotlin (컬렉션, 리스트 List, 셋 Set, 맵 Map)

Walker_ 2024. 4. 12. 17:46

1. 컬렉션 

 - 자바에서도 리스트 List, 셋 Set, 맵 Map 등 여러 자료 구조를 사용

 - 코틀린에서도 이러한 컬렉션을 모두 사용할 수 있을 뿐만 아니라 몇 가지 편리한 함수를 추가로 제공

 - 또한 코틀린은 컬렉션을 읽기전용 immutabel 컬렉션과 읽기-쓰기 mutable 컬렉션으로 크게 두 가지로 나눔

fun main() {
    /*
    1. 리스트
    리스트 List는 저장되는 데이터에 1) 인덱스를 부여한 컬렉션이며 2) 중복된 값을 입력할 수 있음
    코틀린에서 동적으로 리스트를 사용하기 위해서는 리스트 자료형 앞에 뮤터블 Mutable 이라는 접두어 prefix가 붙음
    접두어가 있는 리스트도 있지만 잘 사용하지 않기 때문에 항상 mutableList, mutableMap, mutableSet을 사용
    
    * 뮤터블
    프로그래밍 언어에서 뮤터블은 변할 수 있는 데이터 타입을 가르키는 용어. 변수로는 var이 뮤터블.
    그리고 반대 개념인 이뮤터블 Immutable이 있는데 이것은 val과 값이 변할 수 없는 데이터 타입을 가르키는 용어
    
    코틀린은 컬렉션 데이터 타입을 설계할 때 모두 이뮤터블로 설계
    기본 컬렉션인 리스트, 맵, 셋은 모두 한 번 입력된 값을 바꿀 수 없음
    그래서 컬렉션의 원래 용도인 동적 배열로 사용하기 위해서는 뮤터블로 만들어진 데이터 타입을 사용해야 함
    
    먼저 읽기 전용 리스트를 만들 것인지, 읽기 쓰기 모두 가능한 리스트를 만들 것인지를 정한 후,
    목적에 맞는 함수를 사용해 리스트를 만들어야 함.
    
    읽기 전용 리스트는 listOf() 함수를 사용
     */
    val numList = listOf(1,2,3)
    println(numList[1]) // 2
//    numList[0] = 10 // 오류 발생

    /*
    numList[0] = 10에서 오류가 발생하는데, 그 이유는 리스트가 immutable(읽기 전용)이기 때문.

    읽기 쓰기 모두 가능한 리스트를 만들려면 mutableListOf() 함수를 사용하면 됨

    1) 리스트 생성하기 : mutableListOf
     */
    val mutableList = mutableListOf("MON", "TUE", "WED") // 3개의 값을 가진 크기가 3인 동적 배열 리스트가 생성

    /*
    2) 리스트에 값 추가하기 : add
    mutableList 변수에 add 메서드를 사용해서 값을 추가
    값이 추가되면서 동적으로 리스트의 공간이 자동으로 증가
     */
    mutableList.add("THU") // 입력될 위치인 인덱스를 따로 지정해주지 않아도 입력되는 순서대로 인덱스가 지정
    println(mutableList) // [MON, TUE, WED, THU]

    /*
    3) 리스트에 입력된 값 사용하기 : get
    입력할 때와는 다르게 사용할 때는 인덱스를 지정해서 몇번째 값을 꺼낼 것인지 명시
     */
    var variable = mutableList.get(1) // 두 번째 값을 변수에 저장
    variable = mutableList[1] // 대괄호 사용도 가능
    println(variable)

    /*
    4) 리스트 값 수정하기 : set
    특정 인덱스값을 수정
     */

    mutableList.set(1, "수정할 값") // 두 번째 값을 수정
    println(mutableList) // [MON, 수정할 값, WED, THU]
    mutableList[1] = "수정할 값2" // 두 번째 값을 숫정
    println(mutableList) // [MON, 수정할 값2, WED, THU]

    /*
    5) 리스트에 입력된 값 제거하기 : removeAt
    리스트에 입력된 값의 인덱스를 지정해서 삭제
     */

    println(mutableList)
    mutableList.removeAt(1) // 두 번째 값을 삭제
    // 두 번째 값을 삭제하면서 세 번째 값부터 인덱스가 하나씩 감소하면서 빈자리의 인덱스로 이동
    println(mutableList.get(1)) // WED

    /*
    6) 빈 리스트 사용하기
    아무것도 없는 빈 리스트를 생성하면 앞으로 입력되는 데이터 타입을 알 수 없기 때문에 값의 타입을 추론할 수 없음
    그래서 빈 컬렉션의 경우 앞에서처럼 '데이터타입of'만으로는 생성되지 않고 데이터 타입을 직접적으로 알려주는 방법을 사용해야 함

    var 변수명 = mutableListOf<컬렉션에 입력될 값의 타입>()
    var stringList = mutableLsitOf<String>()
     */
    // 생성
    val stringList = mutableListOf<String>()// 문자열로 된 빈 컬렉션을 생성
    stringList.add("월")
    stringList.add("화")
    stringList.add("수")
    println(stringList)
    
    // 수정
    stringList.set(1, "수정할 값")
    
    // 삭제
    stringList.removeAt(1) // 두번째 값 선택
    
    /*
    7) 컬렉션개수 가져오기 : size
    프로퍼티를 사용하면 컬렉션의 개수를 가져올 수 음
     */
    println("stringList에는 ${stringList.size}개의 값이 있습니다.")
}

 

2. 연습문제

fun main() {
    val mutableList = mutableListOf<String>();

    for (i in 0..4){
        print("문자를 입력해주세요 : ")
        var str = readln()
        mutableList.add(str)
    }
    println(mutableList)

    val immutableList = listOf('a', 'b', 'c', 'd', 'e');
    println(immutableList)
}

 

3. 셋 Set 

 - 셋은 중복을 허용하지 않는 리스트라고 할 수 있음

 - 리스트와 유사한 구조이지만 인덱스로 조회할 수 없고, get() 메서드도 지원하지 않음

 

 - 중복되지 않은 요소들로 만들어지므로 같은 값을 추가하더라도 해당 값은 하나만 저장 

 - 리스트와 마찬가지로 읽기 전용 셋과 읽기 쓰기 모두 가능한 셋, 총 두가지를 제공

 - 각각 setOf(), mutableSetOf() 함수로 객체를 생성

fun main() {
    // 읽기 전용 셋
    val immutableSet = setOf(1,1,2,2,3,3)
    println(immutableSet) // [1, 2, 3]

    // 읽기, 쓰기 가능 셋
    // 1) 빈 셋으로 초기화하고 값 입력하기
    var set = mutableSetOf<String>()
    set.add("JAN")
    set.add("FEB")
    set.add("MAR")
    set.add("JAN") // 셋은 중복을 허용하지 않기 때문에 동일한 값은 입력되지 않음

    // 2) 셋 사용하기
    // 인덱스로 조회하는 메서드가 없기 때문에 특정 위치의 값을 직접 사용할 수 없음
    println("Set 전체 출력 : ${set}") // Set 전체 출력 : [JAN, FEB, MAR]

    // 3) 삭제하기
    // 값이 중복되지 않기 때문에 값으로 직접 조회해서 삭제 할 수 있음
    set.remove("FEB")
    println("Set 전체 출력 : ${set}") // Set 전체 출력 : [JAN, MAR]

    // 읽기 쓰기 모두 가능한 셋
    val mutableSet = mutableSetOf(1,1,2,2,2,3,3)
    println(mutableSet.add(100)) // true
    println(mutableSet.add(3)) // false 이미 있기에 false

    mutableSet.remove(1)
    mutableSet.remove(200)

    println(mutableSet) // [2,3,100]
    println(mutableSet.contains(1))
}

 

4. 맵 Map 

 - 맵은 키 Key와 값 Value의 쌍으로 입력되는 컬렉션

 - 맵의 키는 리스트의 인덱스와 비슷한데 맵에는 키를 직접 입력해야 함

 - 키는 중복되지 않도록 해야 함

 - 제네릭으로 키와 값의 데이터 타입을 지정해서 맵을 생성

 - 맵의 요소는 Pair(A, B)를 사용하는데 이는 A to B로도 표현할 수 있음

fun main() {
    // 읽기 전용 맵
    val immutableMap = mapOf("name" to "tom", "age" to 28, "age" to 20, "height" to 170)
    println(immutableMap)

    /*
    1) 맵 생성하기
    키와 값이 데이터 타입을 모두 String으로 사용
     */
    var map = mutableMapOf<String, String>()

    /*
    2) 값 추가하기
    값을 추가하기 위해 제공되는 put 메서드에 키와 값을 입력
     */

    map.put("키1", "값1")
    map.put("키2", "값2")
    map.put("키3", "값3")

    /*
    3) 맵 사용하기
    get 메서드에 키를 직접 입력해서 값을 사용할 수 있음
     */

    println("map에 입력된 키1의 값은 ${map.get("키1")}입니다.")

    /*
    4) 맵 수정하기
    put() 메서드를 사용할 때 동일한 키를 가진 값이 있으면 키는 유지된 채로 값만 수정
     */
    
    map.put("키2", "수정한 값")
    println("map에 입력된 키2의 값은 ${map.get("키2")}입니다.")
    map["키2"] = "수정한 값 !!"
    println("map에 입력된 키2의 값은 ${map.get("키2")}입니다.")

    /*
    5) 맵 삭제하기
    remove() 메서드에 키를 입력해 값을 삭제 할 수 있음
     */

    map.remove("키1")

    // 없는 값을 불러오면 null값이 출력됨
    println("map에 입력된 키1의 값은 ${map.get("키1")}입니다.")

}

 

 


공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.

부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.

읽어주셔서 감사합니다 :)