来自 Java
背景,我习惯于处理集合的常见做法:显然会有异常(exception),但通常代码如下所示:
public class MyClass {
private Set<String> mySet;
public void init() {
Set<String> s = new LinkedHashSet<String>();
s.add("Hello");
s.add("World");
mySet = Collections.unmodifiableSet(s);
}
}
我不得不承认,我对 Scala 中过多的选项感到有些困惑。有:
scala.List
(和Seq
)scala.collections.Set
(和Map
)scala.collection.immutable.Set
(和Map
、Stack
但不是List
)scala.collection.mutable.Set
(和Map
、Buffer
但不是List
)scala.collection.jcl
所以问题!
- 为什么在
scala
包中定义了List
和Seq
而不是scala.collection
(即使实现Seq
在集合子包中)? - 初始化一个集合然后卡住它的标准机制是什么(在Java中这是通过包装在一个
unmodifiable
中来实现的)? - 为什么某些集合类型(例如
MultiMap
)只定义为可变的? (没有不可变的MultiMap
)?
我读过 Daniel Spiewak 的 excellent series on scala collections我仍然对在实践中如何实际使用它们感到困惑。由于强制执行完整的包声明,以下内容似乎有点笨拙:
class MyScala {
var mySet: scala.collection.Set[String] = null
def init(): Unit = {
val s = scala.collection.mutable.Set.empty[String]
s + "Hello"
s + "World"
mySet = scala.collection.immutable.Set(s : _ *)
}
}
尽管可以说这比 Java 版本更正确,因为不可变集合无法更改(如在 Java 案例中,底层集合可以在 unmodifiable
下更改包装器)
最佳答案
Why are List and Seq defined in package scala and not scala.collection (even though implementations of Seq are in the collection sub-packages)?
因为它们被认为非常有用,以至于它们会通过 scala.Predef 中的同义词自动导入到所有程序中。
What is the standard mechanism for initializing a collection and then freezing it (which in Java is achieved by wrapping in an unmodifiable)?
Java 没有卡住集合的机制。它只有一个习惯用法,用于将(仍可修改的)集合包装在引发异常的包装器中。 Scala 中正确的习惯用法是将可变集合复制到不可变集合中 - 可能使用 :_*
Why are some collection types (e.g. MultiMap) only defined as mutable? (There is no immutable MultiMap)?
团队/社区还没有到达那里。 2.7 分支增加了很多内容,而 2.8 预计还会有更多。
The following seems slightly unwieldy due to the enforced full package declarations:
Scala 允许导入别名,因此在这方面它总是比 Java 更简洁(参见例如 java.util.Date 和 java.sql.Date - 使用这两个强制一个是完全限定的)
import scala.collection.{Set => ISet}
import scala.collection.mutable.{Set => MSet}
class MyScala {
var mySet: ISet[String] = null
def init(): Unit = {
val s = MSet.empty[String]
s + "Hello"
s + "World"
mySet = Set(s : _ *)
}
}
当然,您实际上只需将 init 写为 def init() { mySet = Set("Hello", "World")}
就可以省去所有的麻烦,或者更好的是直接写在构造函数中 var mySet : ISet[String] = Set("Hello", "World")
关于java - Scala 集合标准实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/675381/