ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코틀린] 컬렉션
    코틀린 2022. 3. 7. 12:26

    1. 컬렉션의 특징

    코틀린 컬렉션은 mutable, immutable 두 가지가 구분되어서 제공된다.

    • Pair: 값이 두 개인 튜플
    • Triple: 값이 세 개인 튜플
    • Array: 객체, 원시타입으로 구성된 순번이 있고 크기가 고정된 컬렉션
    • List: 객체들이 정렬된 컬렉션
    • Set: 객체들이 정렬되지 않은 컬렉션
    • Map: 딕셔너리 또는 키와 값의 맵

     

    코틀린이 제공하는 편리한 메소드들

    코틀린은 foreach, map, withIndex등 컬렉션 반복을 위한 메소드들을 제공한다.

    val names = listOf("Park", "Kim")
    
    println(names.withIndex().javaClass) // class kotlin.collections.IndexingIterable
    names.withIndex().forEach {(index, name) -> println("$index $name")}
    // 출력 0 Park, 1 Kim

    withIndex는 리스트나 배열에서 index와 value를 함께 사용할 수 있는 iterator(반복자)를 리턴한다.

     

    2. 페어와 트리플

    코틀린에는 서로 다른 타입의 값들을 간단하게 담을 수 있는 페어와 트리플을 제공한다.

    println(Pair("A", "B")) // (A, B)
    println(Triple("Park", 180, 60)) // (Park, 180, 60)
    println(mapOf("A" to 1, "B" to 2)) // {A=1, B=2}

    to()를 이용해서 페어를 만들 수도 있다.

     

    3. 객체 배열과 primitive 배열

    Array<T>는 코틀린의 배열을 상징한다. arrayOf()함수를 이용해서 배열을 만들 수 있고 []를 이용해서 해당 인덱스의 원소를 조회할 수 있다.

    val nameArray = arrayOf("Park", "Kim")
    println(nameArray::class) // class kotlin.Array
    println(nameArray.javaClass) // class [Ljava.lang.String;
    println("${nameArray[0]} ${nameArray[1]}") // Park Kim

    정수 타입의 배열을 선언에는 arrayOf, intArrayOf 두 가지를 사용할 수 있다.

    정수 타입의 배열은 intArrayOf로 만드는게 좋은데 이 메소드가 원시 타입의 배열을 만들기 때문이다. arrayOf는 Integer 객체로 이루어진 배열을 만들기 때문에 오버헤드가 있다.

    val numbers = intArrayOf(1, 2, 3)
    val numberObjects = arrayOf(1, 2, 3)
    
    println("${numbers::class}, ${numberObjects::class}") //class kotlin.IntArray, class kotlin.Array
    println("${numbers.javaClass}, ${numberObjects.javaClass}") // class [I, class [Ljava.lang.Integer

     

    4. 리스트

    리스트는 mutable, immutable 두 종류가 있다. immutable 리스트는 listOf, mutable 리스트는 mutableListOf로 만들 수 있다.

    val fruits: List<String> = listOf("Apple", "Banana", "Orange")
    println("${fruits[0]} ${fruits.get(0)}") // Apple Apple
    println(fruits::class) // class java.util.Arrays$ArrayList
    println(fruits.javaClass) // class java.util.Arrays$ArrayList

    조회: [] 또는 get 과 인덱스로 원소를 조회할 수 있다.

    println("${"Apple" in fruits} ${fruits.contains("Apple")}") // true true

    contains, in 으로 리스트 내에 원소가 존재하는지를 파악할 수 있다.

    listOf 로 만든 리스트는 변경이 불가능하기 때문에 add같은것을 사용할 수 없다. 내부적으로는 Arrays.asList()로 만든 객체의 뷰로 동작하는데 이 뷰에는 객체에 변화를 줄 수 있는 메소드가 정의되어 있지 않다.

    val addGrape = fruits + "Grape"
    val noOrange = fruits - "Orange"
    println("${addGrape} ${noOrange}")
    // [Apple, Banana, Orange, Grape] [Apple, Banana]

    +, - 를 이용해서 리스트에 존재하는 원소를 조작하고 새 변수에 할당하는 것은 가능하다.

     

    뮤터블리스트가 필요하다면 mutableListOf로 만들 수 있다.

    val mutableFruits = mutableListOf("Apple")
    mutableFruits.add("Banana")
    mutableFruits.add("Orange")
    println(mutableFruits::class) // class java.util.ArrayList
    println(mutableFruits.javaClass) // class java.util.ArrayList

     

    arrayListOf를 이용해서 코틀린 뷰 인터페이스가 아닌 직접 ArrayList<T>의 참조를 얻을 수도 있다.

     

    5. 셋(Set)

    셋은 정렬되지 않은 집합이다. List<T> 처럼 mutable, immutable 버전이 있다.

    • setOf: Set<T>의 인스턴스를 만듬
    • mutableSetOf: mutableSet<T>를 만듬
    • hashSetOf: java.util.HashSet<T>를 만듬
    • linkedSetOf: LinkedHashSet<T>를 만듬
    • sortedSetOf: TreeSet<T>를 만듬
    val nameSet = setOf("Park", "Kim", "Kim")
    println(nameSet) // [Park, Kim]
    println(nameSet::class) // class java.util.LinkedHashSet
    println(nameSet.javaClass) // class java.util.LinkedHashSet

    setOf는 기본적으로 LinkedHashSet을 만든다.

     

    6. 맵(Map)

    맵은 키 - 값으로 이루어진 객체이다.

    • mapOf: Map<K, V>의 맵을 만듬
    • hashMapOf: HashMap<K, V>를 만듬
    • linkedMapOf: LinkedHashMap<K, V> 를 만듬
    • sortedMapOf: SortedMap<K, V>를 만듬
    val simpleMap = mapOf("A" to 1, "B" to 2)
    println(simpleMap) // {A=1, B=2}
    println(simpleMap::class) // class java.util.LinkedHashMap
    println(simpleMap.javaClass) // class java.util.LinkedHashMap

    기본적으로 제공하는 Map 관련 프로퍼티/메소드

    println(simpleMap.keys) // [A, B]
    println(simpleMap.containsKey("A")) // true
    println(simpleMap.containsValue(10)) // false

    Map은 []이나 get으로 값을 조회할 수 있는데 주의할 점은 키가 존재하지 않으면 값이 없으므로 리턴 타입을 Nullable로 선언해야한다.

    val value: Int? = simpleMap.get("C") // Nullable타입으로 리턴됨
    val cAdded = simpleMap + ("C" to 3)
    val noB = simpleMap - "B"
    println(cAdded) // {A=1, B=2, C=3}
    println(noB) // {A=1}

    +, -를 이용해서 원소를 추가하거나 빼는 것도 가능하다.

    for((key, value) in simpleMap) {
        println("$key $value")
    }
    // 출력
    // A 1
    // B 2

    구조분해를 활용하면 반복문에서 맵을 쉽게 활용할 수도 있다.

     

    참고

    다재다능 코틀린프로그래밍 5장

    '코틀린' 카테고리의 다른 글

    [코틀린] 클래스와 상속  (0) 2022.03.13
    [코틀린] 객체와 클래스  (0) 2022.03.13
    [코틀린] 타입 안정성  (0) 2022.03.07
    [코틀린] 외부 반복과 아규먼트 매칭  (0) 2022.03.07
    [코틀린] 함수  (0) 2022.03.06

    댓글

Designed by Tistory.