-
[Kotlin] List,Set,MapKotlin/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