All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kotlin.collections.Maps.kt Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
package kotlin

import java.io.Serializable
import java.util.*

private object EmptyMap : Map, Serializable {
    override fun equals(other: Any?): Boolean = other is Map<*,*> && other.isEmpty()
    override fun hashCode(): Int = 0
    override fun toString(): String = "{}"

    override fun size(): Int = 0
    override fun isEmpty(): Boolean = true

    override fun containsKey(key: Any?): Boolean = false
    override fun containsValue(value: Any?): Boolean = false
    override fun get(key: Any?): Nothing? = null
    override fun entrySet(): Set> = EmptySet
    override fun keySet(): Set = EmptySet
    override fun values(): Collection = EmptyList

    private fun readResolve(): Any = EmptyMap
}

/** Returns an empty read-only map of specified type. The returned map is serializable (JVM). */
public fun emptyMap(): Map = EmptyMap as Map

/**
 * Returns a new read-only map with the specified contents, given as a list of pairs
 * where the first value is the key and the second is the value. If multiple pairs have
 * the same key, the resulting map will contain the value from the last of those pairs.
 *
 * The returned map is serializable (JVM).
 */
public fun mapOf(vararg values: Pair): Map = if (values.size() > 0) linkedMapOf(*values) else emptyMap()

/** Returns an empty read-only map. The returned map is serializable (JVM). */
public fun mapOf(): Map = emptyMap()

/**
 * Returns a new [HashMap] with the specified contents, given as a list of pairs
 * where the first component is the key and the second is the value.
 *
 * @sample test.collections.MapTest.createUsingPairs
 */
public fun  hashMapOf(vararg values: Pair): HashMap {
    val answer = HashMap(mapCapacity(values.size()))
    answer.putAll(*values)
    return answer
}

/**
 * Returns a new [LinkedHashMap] with the specified contents, given as a list of pairs
 * where the first component is the key and the second is the value.
 * This map preserves insertion order so iterating through the map's entries will be in the same order.
 *
 * @sample test.collections.MapTest.createLinkedMap
 */
public fun  linkedMapOf(vararg values: Pair): LinkedHashMap {
    val answer = LinkedHashMap(mapCapacity(values.size()))
    answer.putAll(*values)
    return answer
}

/**
 * Calculate the initial capacity of a map, based on Guava's com.google.common.collect.Maps approach. This is equivalent
 * to the Collection constructor for HashSet, (c.size()/.75f) + 1, but provides further optimisations for very small or
 * very large sizes, allows support non-collection classes, and provides consistency for all map based class construction.
 */

private val INT_MAX_POWER_OF_TWO: Int = Int.MAX_VALUE / 2 + 1

private fun mapCapacity(expectedSize: Int): Int {
    if (expectedSize < 3) {
        return expectedSize + 1
    }
    if (expectedSize < INT_MAX_POWER_OF_TWO) {
        return expectedSize + expectedSize / 3
    }
    return Int.MAX_VALUE // any large value
}

/** Returns `true` if this map is not empty. */
public fun  Map.isNotEmpty(): Boolean = !isEmpty()

/**
 * Returns the [Map] if its not `null`, or the empty [Map] otherwise.
 */
public fun  Map?.orEmpty() : Map = this ?: emptyMap()

/**
 * Checks if the map contains the given key. This method allows to use the `x in map` syntax for checking
 * whether an object is contained in the map.
 */
public fun  Map.contains(key : K) : Boolean = containsKey(key)

/**
 * Allows to access the key of a map entry as a property. Equivalent to `getKey()`.
 */
public val  Map.Entry.key: K
    get() = getKey()

/**
 * Allows to access the value of a map entry as a property. Equivalent to `getValue()`.
 */
public val  Map.Entry.value: V
    get() = getValue()

/**
 * Returns the key component of the map entry.
 *
 * This method allows to use multi-declarations when working with maps, for example:
 * ```
 * for ((key, value) in map) {
 *     // do something with the key and the value
 * }
 * ```
 */
public fun  Map.Entry.component1(): K {
    return getKey()
}

/**
 * Returns the value component of the map entry.
 * This method allows to use multi-declarations when working with maps, for example:
 * ```
 * for ((key, value) in map) {
 *     // do something with the key and the value
 * }
 * ```
 */
public fun  Map.Entry.component2(): V {
    return getValue()
}

/**
 * Converts entry to [Pair] with key being first component and value being second.
 */
public fun  Map.Entry.toPair(): Pair {
    return Pair(getKey(), getValue())
}

/**
 * Returns the value for the given key, or the result of the [defaultValue] function if there was no entry for the given key.
 *
 * @sample test.collections.MapTest.getOrElse
 */
public inline fun  Map.getOrElse(key: K, defaultValue: () -> V): V {
    val value = get(key)
    if (value == null && !containsKey(key)) {
        return defaultValue()
    } else {
        return value as V
    }
}

/**
 * Returns the value for the given key. If the key is not found in the map, calls the [defaultValue] function,
 * puts its result into the map under the given key and returns it.
 *
 * @sample test.collections.MapTest.getOrPut
 */
public inline fun  MutableMap.getOrPut(key: K, defaultValue: () -> V): V {
    val value = get(key)
    if (value == null && !containsKey(key)) {
        val answer = defaultValue()
        put(key, answer)
        return answer
    } else {
        return value as V
    }
}

/**
 * Returns an [Iterator] over the entries in the [Map].
 *
 * @sample test.collections.MapTest.iterateWithProperties
 */
public fun  Map.iterator(): Iterator> {
    val entrySet = entrySet()
    return entrySet.iterator()
}

/**
 * Populates the given `destination` [Map] with entries having the keys of this map and the values obtained
 * by applying the `transform` function to each entry in this [Map].
 */
public inline fun > Map.mapValuesTo(destination: C, transform: (Map.Entry) -> R): C {
    for (e in this) {
        val newValue = transform(e)
        destination.put(e.key, newValue)
    }
    return destination
}

/**
 * Populates the given `destination` [Map] with entries having the keys obtained
 * by applying the `transform` function to each entry in this [Map] and the values of this map.
 */
public inline fun > Map.mapKeysTo(destination: C, transform: (Map.Entry) -> R): C {
    for (e in this) {
        val newKey = transform(e)
        destination.put(newKey, e.value)
    }
    return destination
}

/**
 * Puts all the given [values] into this [MutableMap] with the first component in the pair being the key and the second the value.
 */
public fun  MutableMap.putAll(vararg values: Pair): Unit {
    for ((key, value) in values) {
        put(key, value)
    }
}

/**
 * Puts all the elements of the given collection into this [MutableMap] with the first component in the pair being the key and the second the value.
 */
public fun  MutableMap.putAll(values: Iterable>): Unit {
    for ((key, value) in values) {
        put(key, value)
    }
}

/**
 * Puts all the elements of the given sequence into this [MutableMap] with the first component in the pair being the key and the second the value.
 */
public fun  MutableMap.putAll(values: Sequence>): Unit {
    for ((key, value) in values) {
        put(key, value)
    }
}

/**
 * Returns a new map with entries having the keys of this map and the values obtained by applying the `transform`
 * function to each entry in this [Map].
 *
 * @sample test.collections.MapTest.mapValues
 */
public inline fun  Map.mapValues(transform: (Map.Entry) -> R): Map {
    return mapValuesTo(LinkedHashMap(size()), transform)
}

/**
 * Returns a new Map with entries having the keys obtained by applying the `transform` function to each entry in this
 * [Map] and the values of this map.
 *
 * @sample test.collections.MapTest.mapKeys
 */
public inline fun  Map.mapKeys(transform: (Map.Entry) -> R): Map {
    return mapKeysTo(LinkedHashMap(size()), transform)
}

/**
 * Returns a map containing all key-value pairs with keys matching the given [predicate].
 */
public inline fun  Map.filterKeys(predicate: (K) -> Boolean): Map {
    val result = LinkedHashMap()
    for (entry in this) {
        if (predicate(entry.key)) {
            result.put(entry.key, entry.value)
        }
    }
    return result
}

/**
 * Returns a map containing all key-value pairs with values matching the given [predicate].
 */
public inline fun  Map.filterValues(predicate: (V) -> Boolean): Map {
    val result = LinkedHashMap()
    for (entry in this) {
        if (predicate(entry.value)) {
            result.put(entry.key, entry.value)
        }
    }
    return result
}


/**
 * Appends all entries matching the given [predicate] into the mutable map given as [destination] parameter.
 *
 * @return the destination map.
 */
public inline fun > Map.filterTo(destination: C, predicate: (Map.Entry) -> Boolean): C {
    for (element in this) {
        if (predicate(element)) {
            destination.put(element.key, element.value)
        }
    }
    return destination
}

/**
 * Returns a new map containing all key-value pairs matching the given [predicate].
 */
public inline fun  Map.filter(predicate: (Map.Entry) -> Boolean): Map {
    return filterTo(LinkedHashMap(), predicate)
}

/**
 * Appends all entries not matching the given [predicate] into the given [destination].
 *
 * @return the destination map.
 */
public inline fun > Map.filterNotTo(destination: C, predicate: (Map.Entry) -> Boolean): C {
    for (element in this) {
        if (!predicate(element)) {
            destination.put(element.key, element.value)
        }
    }
    return destination
}

/**
 * Returns a new map containing all key-value pairs not matching the given [predicate].
 */
public inline fun  Map.filterNot(predicate: (Map.Entry) -> Boolean): Map {
    return filterNotTo(LinkedHashMap(), predicate)
}

/**
 * Returns a new map containing all key-value pairs from the given collection of pairs.
 */
public fun  Iterable>.toMap(): Map {
    val result = LinkedHashMap(collectionSizeOrNull()?.let { mapCapacity(it) } ?: 16)
    for (element in this) {
        result.put(element.first, element.second)
    }
    return result
}

/**
 * Returns a new map containing all key-value pairs from the given array of pairs.
 */
public fun  Array>.toMap(): Map {
    val result = LinkedHashMap(mapCapacity(size()))
    for (element in this) {
        result.put(element.first, element.second)
    }
    return result
}

/**
 * Returns a new map containing all key-value pairs from the given sequence of pairs.
 */

public fun  Sequence>.toMap(): Map {
    val result = LinkedHashMap()
    for (element in this) {
        result.put(element.first, element.second)
    }
    return result
}

/**
 * Converts this [Map] to a [LinkedHashMap], maintaining the insertion order of elements added to that map afterwards.
 */
public fun  Map.toLinkedMap(): MutableMap = LinkedHashMap(this)

/**
 * Creates a new read-only map by replacing or adding an entry to this map from a given key-value [pair].
 */
public fun  Map.plus(pair: Pair): Map {
    val newMap = this.toLinkedMap()
    newMap.put(pair.first, pair.second)
    return newMap
}

/**
 * Creates a new read-only map by replacing or adding entries to this map from a given collection of key-value [pairs].
 */
public fun  Map.plus(pairs: Iterable>): Map {
    val newMap = this.toLinkedMap()
    newMap.putAll(pairs)
    return newMap
}

/**
 * Creates a new read-only map by replacing or adding entries to this map from a given array of key-value [pairs].
 */
public fun  Map.plus(pairs: Array>): Map {
    val newMap = this.toLinkedMap()
    newMap.putAll(*pairs)
    return newMap
}

/**
 * Creates a new read-only map by replacing or adding entries to this map from a given sequence of key-value [pairs].
 */
public fun  Map.plus(pairs: Sequence>): Map {
    val newMap = this.toLinkedMap()
    newMap.putAll(pairs)
    return newMap
}

/**
 * Creates a new read-only map by replacing or adding entries to this map from another [map].
 */
public fun  Map.plus(map: Map): Map {
    val newMap = this.toLinkedMap()
    newMap.putAll(map)
    return newMap
}

/**
 * Appends or replaces the given [pair] in this mutable map.
 */
public fun  MutableMap.plusAssign(pair: Pair) {
    put(pair.first, pair.second)
}

/**
 * Appends or replaces all pairs from the given collection of [pairs] in this mutable map.
 */
public fun  MutableMap.plusAssign(pairs: Iterable>) {
    putAll(pairs)
}

/**
 * Appends or replaces all pairs from the given array of [pairs] in this mutable map.
 */
public fun  MutableMap.plusAssign(pairs: Array>) {
    putAll(*pairs)
}

/**
 * Appends or replaces all pairs from the given sequence of [pairs] in this mutable map.
 */
public fun  MutableMap.plusAssign(pairs: Sequence>) {
    putAll(pairs)
}

/**
 * Appends or replaces all entries from the given [map] in this mutable map.
 */
public fun  MutableMap.plusAssign(map: Map) {
    putAll(map)
}

/**
 * Creates a new read-only map by removing a [key] from this map.
 */
public fun  Map.minus(key: K): Map {
    val result = LinkedHashMap(this)
    result.minusAssign(key)
    return result
}

/**
 * Creates a new read-only map by removing a collection of [keys] from this map.
 */
public fun  Map.minus(keys: Iterable): Map {
    val result = LinkedHashMap(this)
    result.minusAssign(keys)
    return result
}

/**
 * Creates a new read-only map by removing a array of [keys] from this map.
 */
public fun  Map.minus(keys: Array): Map {
    val result = LinkedHashMap(this)
    result.minusAssign(keys)
    return result
}

/**
 * Creates a new read-only map by removing a sequence of [keys] from this map.
 */
public fun  Map.minus(keys: Sequence): Map {
    val result = LinkedHashMap(this)
    result.minusAssign(keys)
    return result
}

/**
 * Removes the given [key] from this mutable map.
 */
public fun  MutableMap.minusAssign(key: K) {
    remove(key)
}

/**
 * Removes all the given [keys] from this mutable map.
 */
public fun  MutableMap.minusAssign(keys: Iterable) {
    for (key in keys) remove(key)
}

/**
 * Removes all the given [keys] from this mutable map.
 */
public fun  MutableMap.minusAssign(keys: Array) {
    for (key in keys) remove(key)
}

/**
 * Removes all the given [keys] from this mutable map.
 */
public fun  MutableMap.minusAssign(keys: Sequence) {
    for (key in keys) remove(key)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy