Scala - 初始化容器的多种方法

时间:2015-11-05 18:34:21

标签: scala containers

我是Scala的新手,想知道使用以下三种方式初始化Map数据结构有什么区别:

 private val currentFiles: HashMap[String, Long] = new HashMap[String, Long]()
 private val currentJars = new HashMap[String, Long]
 private val currentVars = Map[String, Long]

2 个答案:

答案 0 :(得分:3)

您的问题有两个不同的部分。

首先,使用显式类型(案例1和案例2)之间的区别适用于任何类,不一定是容器。

 val x = 1

这里的类型不明确,编译器会尝试使用类型推断来解决它。 x的类型为Int

val x: Int = 1

与上述相同,但现在明确说明。如果=右边的任何内容无法转换为Int,则会出现编译错误。

val x: Any = 1

这里我们仍将存储1,但变量的类型将是父类,使用多态。

问题的第二部分是初始化。基本初始化与java中一样:

val x = new List[Int]()

这将调用类构造函数并返回确切类的新实例。 现在,有一个名为.apply的特殊方法,您可以使用括号来定义和调用,如下所示:

val x = Seq[Int]()

这是一个快捷方式:

val x = Seq.apply[Int]()

请注意,这是Seq对象上的一个函数。返回类型是函数想要的任何东西,它只是另一个函数。也就是说,它主要用于返回给定类型的新实例,但是没有保证,您需要查看函数文档以确保合同。

也就是说,在val x = Map[String, Long]()的情况下,实现返回immutable.HashMap[String, Long]的实际实例,这是一种默认的Map实现。

答案 1 :(得分:2)

MapHashMap几乎相同,但不完全相同。

Map是特质,HashMap是一个类。尽管在幕后他们可能是同一件事(scala.collection.immutable.HashMap)(稍后会详细介绍)。

使用时

private val currentVars = Map[String, Long]()

您获得了Map个实例。在scala中,()是一个糖,你实际上是在调用object Mapapply()方法。这相当于:

private val currentVars = Map.apply[String, Long]()

使用

private val currentJars = new HashMap[String, Long]()

你得到一个HashMap实例。

在第三个声明中:

private val currentJars: HashMap[String, Long] = new HashMap[String, Long]()

你只是不再依赖type inference了。这与第二个语句完全相同

private val currentJars: HashMap[String, Long] = new HashMap[String, Long]()
private val currentJars = new HashMap[String, Long]() // same thing

何时/我使用/为什么

关于类型推断,我建议你使用类型推断。在这种情况下,恕我直言,它从代码中删除了实际上不需要的详细程度。但如果您真的错过了类似java代码,那么请包含类型:)。

现在,关于两个构造函数......

Map vs HashMap

简短回答

你应该总是使用Map():它更短,已经导入并返回一个特征(如java界面)。最后一个原因很好,因为当你传递这个Map时,你不会依赖于实现细节,因为Map只是你想要或需要的接口。

另一方面,HashMap 是一种实现。

答案很长

Map并非总是HashMap

如在 Scala编程中所见,Map.apply[K, V]()可以返回一个不同的类,具体取决于您传递给它的键值对(ref):

Number of elements       Implementation

0                        scala.collection.immutable.EmptyMap

1                        scala.collection.immutable.Map1 

2                        scala.collection.immutable.Map2

3                        scala.collection.immutable.Map3

4                        scala.collection.immutable.Map4 

5 or more                scala.collection.immutable.HashMap

当你有少于5个元素时,你会为每个小集合获得一个特殊的类,当你有一个空的Map时,你会得到一个单例对象。

这主要是为了获得更好的表现。

您可以在repl中尝试:

import scala.collection.immutable.HashMap

val m2 = Map(1 -> 1, 2 -> 2)
m2.isInstanceOf[HashMap[Int, Int]]
// false

val m5 = Map(1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4, 5 -> 5, 6 -> 6)
m5.isInstanceOf[HashMap[Int, Int]]
// true

如果你真的很好奇,你甚至可以看看source code

因此,即使是表现,你也应该坚持使用Map()