如何将Scala Map转换为scala.collection.immutable.HashMap?

3

由于某种奇怪的原因,只有在scala.collection.immutable.HashMap中声明了一个方法merged,而在通用的Map特质中却没有(也许它的实现使得其他Map实现非常难以接受?)。

因此,我需要将我的Map[A, B]转换为HashMap[A, B],但到目前为止,我找不到一个简单的方法来实现这一点。下面是我当前的实现方式,它可以绕过期望一元高级别而不是二元高级别的def to[Col[_]]方法。

val m1 = Map("foo" -> 1)
val m2 = Map("foo" -> 2, "bar" -> 2)

type HM[_] = HashMap[String, Int]
(m1.to[HM] merged m2.to[HM]) { case ((k1, v1), (k2, v2)) => (k1, v1 + v2) } // Map("foo" -> 3, "bar" -> 2)

它按预期工作,但我不禁想到一定有更好的方法将Map转换为HashMap(考虑到它是默认实现)。

或者更普遍地说,是否有更好的方法来访问Scala集合通用特征的默认实现?


也许可以使用 HashMap(m1.toSeq: _*)?请参考 https://dev59.com/pmw05IYBdhLWcg3wuT8L 了解其他合并映射的选项。 - Łukasz
如果您使用的操作仅在HashMap中可用,为什么不一开始就将您的映射声明为HashMap呢? - Rüdiger Klaehn
@Łukasz 是的,我看过那个问题,但是我的代码这部分非常注重性能,使用 toSeq 将需要 2 次迭代。同样,merged 被认为非常高效,所以最好使用它。 - Daniel Shin
@RüdigerKlaehn 因为我通过在数组上调用toMap来获得这些映射。如果可能的话,我不想手动将其折叠成HashMap - Daniel Shin
如果你想要快速处理,你可能需要将数组转换为 HashMap.empty[String, Int] ++ array。为了在一行内完成这个操作,你需要帮助类型推断器避免再次得到一个普通的 Map。可以使用 ((HashMap.empty ++ array): HashMap[String, Int]) merged ... - Łukasz
为什么不直接将数组转换为HashMap(就像您在这里使用to一样)?创建一个中间的Map有什么意义吗? - Régis Jean-Gilles
3个回答

0
你可以从一个空的 HashMap 开始,然后将所有元素添加进去:
immutable.HashMap.empty ++= yourMap

OP 希望使用 immutable.HashMap - Łukasz
@Łukasz:修复了,也没有太大的区别。 - Roman
1
应该只是 ++,而不是 ++= - Ben

0

这并不是回答你的问题,但它是解决你问题的方法。 以下步骤可以更快地完成:

  1. 实现你需要用于 map 的 merged 方法,
  2. 使用 map 上定义的 ++ 方法进行合并。

0
假设原始映射已经是一个immutable.HashMap,最有效的转换方式是immutable.HashMap.from(originalMap),因为当它已经是immutable.HashMap时,它会返回原始映射。
但请注意,只有大小大于4时,immutable.Map构造函数才会构建一个immutable.HashMap
scala> val generic4 = Map("a" -> 1, "b" -> 2, "c" -> 3,  "d" -> 4)
val generic4: Map[String, Int] = Map(a -> 1, b -> 2, c -> 3, d -> 4)

scala> generic4.getClass
val res5: Class[? <: Map[String, Int]] = class scala.collection.immutable.Map$Map4

scala> val generic5 = Map("a" -> 1, "b" -> 2, "c" -> 3,  "d" -> 4, "e" -> 5)
val generic5: Map[String, Int] = HashMap(e -> 5, a -> 1, b -> 2, c -> 3, d -> 4)

scala> generic5.getClass
val res6: Class[? <: Map[String, Int]] = class scala.collection.immutable.HashMap

scala> val specific5 = HashMap.from(generic5)
val specific5: scala.collection.immutable.HashMap[String, Int] = HashMap(e -> 5, a -> 1, b -> 2, c -> 3, d -> 4)

scala> specific5 eq generic5
val res7: Boolean = true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接