ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kotlin] List,Set,Map
    Kotlin/Collection 2021. 9. 5. 16:09

    2021.08.26 - [Kotlin/Collection] - [Kotlin] Collection hierachy

    List<T>

    In Kotlin, the default implementation of List is ArrayList


    Two lists are considered equal if they have the same sizes and structurally equal elements at the same positions.

    class Person(var name:String, var age:Int)
    
    fun main() {
        val bob = Person("Bob", 31)
        val people = listOf(Person("Adam", 20), bob, bob)
        val people2 = listOf(Person("Adam", 20), Person("Bob", 31), bob)
        println(people == people2)
    
    }
    true

    Set<T>

    LinkedHashSet( 코틀린 Set의 기본구현 )

    대안 HashSet

    says nothing about the elements order, so calling such functions on it returns unpredictable results. However, HashSet requires less memory to store the same number of elements.


    store unique element ->  can contain only one null

    Two sets are equal if they have the same size, and for each element of a set

    fun main() {
        val numbers = setOf(1, 2, 3, 4)
        val numbersBackwards = setOf(4, 3, 2, 1)
        println("The sets are equal: ${numbers == numbersBackwards}")
    }
    The sets are equal: true

    val numbers = setOf(1, 2, 3, 4)  // LinkedHashSet is the default implementation
    val numbersBackwards = setOf(4, 3, 2, 1)
    
    println(numbers.first() == numbersBackwards.first())
    println(numbers.first() == numbersBackwards.last())
    false
    true

    Map<K, V>

    LinkedHashMap(default implementation of Map)

    preserves the order of elements insertion when iterating the map. In turn, an alternative implementation

     

    HashMap

    says nothing about the elements order.

    @file:Suppress("ACTUAL_WITHOUT_EXPECT") // for building kotlin-stdlib-minimal-for-test
    
    package kotlin.collections
    
    @SinceKotlin("1.1") public actual typealias RandomAccess = java.util.RandomAccess
    
    
    @SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
    @SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
    @SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
    @SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
    @SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>

    함수 -> 리턴타입

    mapOf 함수 -> 코틀린 Map (불변)

    hashMapOf 함수 -> 코틀린 HashMap( java.util.HashMap) (가변)

    linkedMapOf 함수 -> 코틀린 LinkedHashMap( java.util.LinkedHashMap) (가변+ 순서존재)

    sortedMapOf 함수 -> 코틀린 SortedMap ( java.util.SortedMap) (가변 + 순서존재 + key값에 따라 정렬


    interface Map

     

    Collections.kt

    public interface Map<K, out V> {
        // Query Operations
        /**
         * Returns the number of key/value pairs in the map.
         */
        public val size: Int
    
        /**
         * Returns `true` if the map is empty (contains no elements), `false` otherwise.
         */
        public fun isEmpty(): Boolean
    
        /**
         * Returns `true` if the map contains the specified [key].
         */
        public fun containsKey(key: K): Boolean
    
        /**
         * Returns `true` if the map maps one or more keys to the specified [value].
         */
        public fun containsValue(value: @UnsafeVariance V): Boolean
    
        /**
         * Returns the value corresponding to the given [key], or `null` if such a key is not present in the map.
         */
        public operator fun get(key: K): V?
    
        /**
         * Returns the value corresponding to the given [key], or [defaultValue] if such a key is not present in the map.
         *
         * @since JDK 1.8
         */
        @SinceKotlin("1.1")
        @PlatformDependent
        public fun getOrDefault(key: K, defaultValue: @UnsafeVariance V): V {
            // See default implementation in JDK sources
            throw NotImplementedError()
        }
    
        // Views
        /**
         * Returns a read-only [Set] of all keys in this map.
         */
        public val keys: Set<K>
    
        /**
         * Returns a read-only [Collection] of all values in this map. Note that this collection may contain duplicate values.
         */
        public val values: Collection<V>
    
        /**
         * Returns a read-only [Set] of all key/value pairs in this map.
         */
        public val entries: Set<Map.Entry<K, V>>
    
        /**
         * Represents a key/value pair held by a [Map].
         */
        public interface Entry<out K, out V> {
            /**
             * Returns the key of this key/value pair.
             */
            public val key: K
    
            /**
             * Returns the value of this key/value pair.
             */
            public val value: V
        }
    }

    Immutable Empty Map 생성

    fun main() {
        val emptyMap: Map<String, String> = mapOf()
    }

     

     

    Maps.kt

     

    mapOf()

    @kotlin.internal.InlineOnly
    public inline fun <K, V> mapOf(): Map<K, V> = emptyMap()
    public fun <K, V> emptyMap(): Map<K, V> = @Suppress("UNCHECKED_CAST") (EmptyMap as Map<K, V>)
    private object EmptyMap : Map<Any?, Nothing>, Serializable {
        private const val serialVersionUID: Long = 8246714829545688274
    
        override fun equals(other: Any?): Boolean = other is Map<*, *> && other.isEmpty()
        override fun hashCode(): Int = 0
        override fun toString(): String = "{}"
    
        override val size: Int get() = 0
        override fun isEmpty(): Boolean = true
    
        override fun containsKey(key: Any?): Boolean = false
        override fun containsValue(value: Nothing): Boolean = false
        override fun get(key: Any?): Nothing? = null
        override val entries: Set<Map.Entry<Any?, Nothing>> get() = EmptySet
        override val keys: Set<Any?> get() = EmptySet
        override val values: Collection<Nothing> get() = EmptyList
    
        private fun readResolve(): Any = EmptyMap
    }

    Immutable Map 생성

    fun main() {
        val map: Map<String, String> = mapOf("1" to "1", "2" to "2", "3" to "3")
    }

     

    Tuples.kt

    public data class Pair<out A, out B>(
        public val first: A,
        public val second: B
    ) : Serializable {
    
        /**
         * Returns string representation of the [Pair] including its [first] and [second] values.
         */
        public override fun toString(): String = "($first, $second)"
    }
    
    /**
     * Creates a tuple of type [Pair] from this and [that].
     *
     * This can be useful for creating [Map] literals with less noise, for example:
     * @sample samples.collections.Maps.Instantiation.mapFromPairs
     */
    public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
    
    /**
     * Converts this pair into a list.
     * @sample samples.misc.Tuples.pairToList
     */
    public fun <T> Pair<T, T>.toList(): List<T> = listOf(first, second)

    Pair인스턴스를 리턴하는 infix function to -> A to B

     

    mapOf(vararg paris: Pair<K,V>)

    public fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V> =
        if (pairs.size > 0) pairs.toMap(LinkedHashMap(mapCapacity(pairs.size))) else emptyMap()

    mapCapacity()

    @PublishedApi
    internal expect fun mapCapacity(expectedSize: Int): Int

    LinkedHashMap

    package kotlin.collections
    
    expect class LinkedHashMap<K, V> : MutableMap<K, V> {
        constructor()
        constructor(initialCapacity: Int)
        constructor(initialCapacity: Int, loadFactor: Float)
        constructor(original: Map<out K, V>)
    
        // From Map
    
        override val size: Int
        override fun isEmpty(): Boolean
        override fun containsKey(key: K): Boolean
        override fun containsValue(value: V): Boolean
        override fun get(key: K): V?
    
        // From MutableMap
    
        override fun put(key: K, value: V): V?
        override fun remove(key: K): V?
        override fun putAll(from: Map<out K, V>)
        override fun clear()
        override val keys: MutableSet<K>
        override val values: MutableCollection<V>
        override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
    }

    inline function contains

    @kotlin.internal.InlineOnly
    public inline operator 
    fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.contains(key: K): Boolean 
    = containsKey(key)

    내부적으로 자신의 containsKey메서드 호출

    map에서 key유무 확인

    "키" in map변수 -> map.contains(1)

    https://kotlinlang.org/docs/operator-overloading.html#in-operator


    map의 value Set에서 value유무 확인

    "값" in map변수.values

    public interface Collection<out E> : Iterable<E> {
        // Query Operations
        /**
         * Returns the size of the collection.
         */
        public val size: Int
    
        /**
         * Returns `true` if the collection is empty (contains no elements), `false` otherwise.
         */
        public fun isEmpty(): Boolean
    
        /**
         * Checks if the specified element is contained in this collection.
         */
        public operator fun contains(element: @UnsafeVariance E): Boolean
    
        override fun iterator(): Iterator<E>
    
        // Bulk Operations
        /**
         * Checks if all elements in the specified collection are contained in this collection.
         */
        public fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean
    }

    Example

    fun main(){
        val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
    
        println("All keys: ${numbersMap.keys}")
        println("All values: ${numbersMap.values}")
        if ("key2" in numbersMap) println("Valuse by key \"key2\": ${numbersMap["key2"]}")
        if (1 in numbersMap.values) println("The value 1 is in the map")
        if (numbersMap.containsValue(1)) println("The value 1 is in the map") // same as previou
    }
    All keys: [key1, key2, key3, key4]
    All values: [1, 2, 3, 1]
    Valuse by key "key2": 2
    The value 1 is in the map
    The value 1 is in the map

    fun main(){
        val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
        val anotherMap = mapOf("key2" to 2, "key1" to 1, "key4" to 1, "key3" to 3)
    
        println("The maps are equal: ${numbersMap == anotherMap}")
    }
    The maps are equal: true

    Mutable Map

    is a Map with map write operations, for example, you can add a new key-value pair or update the value associated with the given key.

    fun main(){
        val numbersMap = mutableMapOf("one" to 1, "two" to 2)
        numbersMap.put("three", 3)
        numbersMap["one"] = 11
    
        println(numbersMap)
    }
    {one=11, two=2, three=3}

     

     

    'Kotlin > Collection' 카테고리의 다른 글

    [Kotlin] Collection hierachy  (0) 2021.08.26

    댓글

Designed by Tistory.