为什么 Scala 中的 Map 自动导入,但 HashMap 却没有?

5
如果使用map,则无需导入不可变的map
scala> val map=Map[String,Int]()
map: scala.collection.immutable.Map[String,Int] = Map()

但是如果我们使用HashMap,没有进行导入就会出现错误。

scala> val a=HashMap[Int,Int]()
 <console>:7: error: not found: value HashMap
       val a=HashMap[Int,Int]()
             ^

但是,如果使用import scala.collection.immutable.HashMap,则可以正常工作。
我也在Set和Hashset中看到了这个问题...
我注意到一个事情,Map和Set是trait而HashSet和HashMap是classes。
那么为什么会这样呢?
编辑:
Stack和Queue类也存在于scala.collection包中。那么为什么我们需要导入这些类呢?

val map = Map()会做同样的事情,因为Map是不可变的。而且> map + ("Ahoy" -> 0) 也可以工作,这要归功于协变。 - jwinandy
关于栈(Stack)和队列(Queue),我认为它们比起列表(List)、集合(Set)和映射(Map)使用得要少得多。 - om-nom-nom
我不确定,但我认为这些类似于HashMap。因此它们并没有自动导入,就像您的答案“针对接口编程而非实现”建议的那样。 - Rishi
我刚刚撤销了编辑,因为它完全改变了原始帖子的措辞(而且在我看来并没有改善),不仅仅是“添加了缺失标签,创建了段落”那么简单。 - The Archetypal Paul
4个回答

14

3
这是因为 Predef 被隐式导入。它包含了常见特质的工厂方法,例如 MapHashMap 是一个具体实现,所以如果你使用它的工厂方法进行类型推断,你会将声明与实现紧密耦合。

为什么Map被列入Predef,而HashMap没有? - om-nom-nom

1
在Scala中,惯用不可变类型,因此默认提供这些类型。如果需要改变,则必须明确表示。
另一个潜在的原因(我只是猜测)是HashMap是Map的一种,在许多情况下,您并不真正关心得到的具体Map实现,您只需要能够将键与值关联起来并具有合理快速的查找功能。因此,仅使用Map("foo" -> "bar")比使用HasArrayMappedTrie("foo" -> "bar")更抽象。

但是,如果我们尝试在没有导入scala.collection.immutable.Queue的情况下使用不可变队列,则它将无法工作。虽然Map和Queue都在scala.collection包中,但为什么会这样呢? - Rishi
1
正如下面thSoft所说,这是因为Predef在所有Scala应用程序中都会自动导入。请参见此行,了解Map何时可用。 - overthink
尽管需要注意的是,不可变类型比可变类型更受青睐,但实际上有一个不可变的HashMap实现,因此你的第二个原因可能更重要。 - thSoft

0
它可能与该集合类的层次结构有关:

enter image description here


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