Skip to content

Latest commit

 

History

History
117 lines (83 loc) · 4 KB

map-copying.md

File metadata and controls

117 lines (83 loc) · 4 KB

Extensions to copy map contents

  • Type: Standard Library API proposal
  • Author: Ilya Gorbunov
  • Status: Implemented in Kotlin 1.1
  • Prototype: Implemented
  • Target tickets: KT-9108
  • Discussion: KEEP-13

Summary

Standard Library provides several ways to copy collections such as List or Set, but doesn't do so for Maps.

Similar API review

The following table summarizes which operations are available for Lists, Sets and Maps in the Standard Library.

Operation List Set Map
create from elements listOf setOf mapOf
create mutable from elements mutableListOf mutableSetOf mutableMapOf
create special from elements arrayListOf hashSetOf linkedSetOf sortedSetOf hashMapOf linkedMapOf sortedMapOf
create from iterable of elements toList toSet toMap
create mutable from iterable of elements toMutableList toMutableSet -
create special from iterable of elements - toHashSet toSortedSet -
fill target from iterable of elements toCollection(MutableList) toCollection(MutableSet) toMap(MutableMap)
copy of self toList toSet PROPOSED: toMap
mutable copy of self toMutableList toMutableSet PROPOSED: toMutableMap
special copy of self - toHashSet toSortedSet toSortedMap
fill target from self toCollection(MutableList) toCollection(MutableSet) PROPOSED: toMap(MutableMap)

The elements to create map from here are key-value pairs Pair<K,V>.

Description

It is proposed to introduce extensions for map which make various copies of the map contents:

  • Map<out K, V>.toMap(): Map<K, V> - read only copy of map
  • Map<out K, V>.toMutableMap(): MutableMap<K, V> - mutable copy of map
  • Map<out K, V>.toMap(M <: MutableMap<in K, in V>): M - copy map to specified mutable map and return it

Use cases

  1. Defensive read-only copy of map
class ImmutablePropertyBag(map: Map<String, Any>) {
  private val mapCopy = map.toMap()
  
  val setting1: String by mapCopy
  val setting2: Int by mapCopy
}
  1. Making a copy of map to populate it with additional entries later
fun updateMappings(map: MutableMap<String, String>): Unit { ... }

val map: Map<String, String> = ...
val remapped = map.toMutableMap().apply { updateMappings(this) }
  1. Making specialized copy of a map
val map: Map<String, Any> = ...
val treeMap = map.toMap(TreeMap())

Alternatives

  1. Use concrete map implementation constructors
val copy = HashMap(map)
val treeMap = TreeMap(map)

Advantages:

  • allows to presize the map being created to hold all the content of the original map.

Disadvantages:

  • in case 1 produces more specific map than required;
  • requires to decide on concrete implementation in advance;
  • not chaining to the end of operation chain.
  1. Convert map to list of pairs and then back to map
val copy = map.toList().toMap()
val mutableCopy = map.toList().toMap(mutableMapOf())
val treeMap = map.toList().toMap(TreeMap())

Disadvantages:

  • requires to create intermediate list of pairs, can cause significant GC pressure.
  1. To populate destination map, use its destination.putAll(this) method instead of this.toMap(destination).

Disadvantages:

  • putAll returns Unit, so it doesn't chain well.

Dependencies

A subset of Kotlin Standard Library available on all supported platforms.

Placement

  • module kotlin-stdlib
  • package kotlin.collections

Reference implementation

The final implementation has been merged into the standard library, here is the commit set.

Future advancements

  • Functions to create mutable or special map from iterable of elements.
  • Functions to create maps from iterable of Map.Entry.