2016-07-26 2 views

ответ

6

Следующая функция расширения работает путем копирования Map на MutableMap.

fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> { 
    return HashMap(this) 
} 
9

Во-первых, так как покрыты предыдущие вопросы о Котлин читать только коллекции и их неизменность, они действительно только для чтения жить вид вероятных изменяемых коллекций.

Котлина можно смело проверить тип для изменчивости для них, так как есть маркеры на интерфейсах, которые позволяют Котлину знать, например:

// assuming some variable readOnlyMap of type Map<String, String> 

val mutableMap: MutableMap<String, String> = if (readOnlyMap is MutableMap<*,*>) { 
    readOnlyMap as MutableMap 
} else { 
    HashMap(readOnlyMap) 
} 

Это is проверки внутренних вызовов TypeIntrinsics.isMutableMap и является допустимым способом знайте, является ли оно литой. Если вы сделаете эту проверку, нет никакой опасности в листинге. Вы заметите, что компилятор абсолютно счастлив и без предупреждений. Это может быть опасно, если вы не собираетесь изменять одну и ту же карту, которая рассматривается как доступная только для чтения, но показывает, что вы можете влиять на нее.

Если вам не нужна возможность изменения исходной карты, то, конечно же, всегда делайте копию, просто вызывая конструктор HashMap с другой Картой, HashMap(readOnlyMap). Или сделать функцию расширения:

fun <K, V> Map<K, V>.toMutableCopy() = HashMap(this) 

и называют его:

val mutableMap = readOnlyMap.toMutableCopy() 

А теперь у вас есть простой способ.

Смотрите также:

+0

Я думаю, что вы должны явно указать генерики HashMap, иначе вы получите карту с типами/значениями платформы. –

+2

Я бы посоветовал проверить 'is MutableMap', поскольку он может возвращать' true' для коллекций Java, которые на самом деле не изменяются. Например, попробуйте 'Collections.unmodifiableMap (mutableMapOf (" a "to" b ")) является MutableMap <*,*>'. –

+0

Это выглядит как лучший ответ для меня. Одна вещь, которую вы можете добавить, - это пример, который не использует 'HashMap' напрямую (я считаю, что' mutableMapOf' фактически использует 'LinkedHashMap'). например: «val mutableMap = map.entries.associateTo (mutableMapOf()) {entry -> entry.toPair()}'. – mfulton26

Смежные вопросы