2012-01-30 1 views
12

Внутри моей функции я построю результирующий набор, заполнив новый измененный HashMap данными (если есть лучший способ - я буду благодарен за комментарии). Затем я хотел бы вернуть результирующий набор как неизменный HashMap. Как получить неизменяемый из изменчивого?Как преобразовать измененный HashMap в неизменный эквивалент в Scala?

ответ

8
scala> val m = collection.mutable.HashMap(1->2,3->4) 
m: scala.collection.mutable.HashMap[Int,Int] = Map(3 -> 4, 1 -> 2) 

scala> collection.immutable.HashMap() ++ m 
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4) 

или

scala> collection.immutable.HashMap(m.toSeq:_*) 
res2: scala.collection.immutable.HashMap[Int,Int] = Map(1 -> 2, 3 -> 4) 
+0

Но результат является 'immutable.Map', а не' immutable.HashMap' тогда! Функция предназначена для возврата 'immutable.HashMap'. – Ivan

+0

Вы можете указать любой тип, который вы хотите. Если вы хотите, чтобы тип был 'Map', do' Map() ++ m' – dhg

+0

Я хочу 'immutable.HashMap', но' immutable.HashMap ++ m' (где 'm' является' mutable.HashMap') возвращает 'immutable.Map'. – Ivan

12

Обсуждение о возвращении immutable.Map vs. immutable.HashMap несмотря на то, что о просто используя toMap метод:

scala> val m = collection.mutable.HashMap(1 -> 2, 3 -> 4) 
m: scala.collection.mutable.HashMap[Int,Int] = Map(3 -> 4, 1 -> 2) 

scala> m.toMap 
res22: scala.collection.immutable.Map[Int,Int] = Map(3 -> 4, 1 -> 2) 

По состоянию на 2.9, это использует метод toMap в TraversableOnce , который реализуется следующим образом:

def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] = { 
    val b = immutable.Map.newBuilder[T, U] 
    for (x <- self) 
     b += x 

    b.result 
} 
+0

Спасибо за введение «Map.newBuilder». Я обычно использовал изменчивые карты только для построения неизменяемых. – akauppi

+0

Есть ли ощутимая разница? Я всегда задавался вопросом, сохраняет ли 'newBuilder' только одну копию данных в памяти или выполняет полную копию данных на' .result', что требует удвоенной суммы памяти? – matanster

+1

Вы можете проверить [источник] (https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/MapBuilder.scala): 'MapBuilder.result' просто возвращает' elems', поэтому он не создает новую копию. Исходя из этого, я понимаю, что это точно так же, как выполнение операции '+' в коллекции * immutable *, а также нет * изменчивой * коллекции. – ebruchez

1

Если у вас есть карта: logMap: Map[String, String] просто нужно сделать: logMap.toMap()