java - Scala 集合标准实践

标签 java scala scala-collections

来自 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(和 MapStack 但不是 List)
  • scala.collection.mutable.Set(和 MapBuffer 但不是 List)
  • scala.collection.jcl

所以问题!

  1. 为什么在 scala 包中定义了 ListSeq 而不是 scala.collection(即使实现Seq 在集合子包​​中)?
  2. 初始化一个集合然后卡住它的标准机制是什么(在Java中这是通过包装在一个unmodifiable中来实现的)?
  3. 为什么某些集合类型(例如 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/

相关文章:

java - 在 Java 中将 WireMock 与 SOAP Web 服务结合使用

performance - 如何在 Scala 中近似数据结构的大小?

scala - 如何让scala的Future运行在当前线程?

scala - 如何将整数列表转换为每个 bin 频率的 map ?

java - 如何在创建 war 文件时设置应用程序上下文?

java - JBoss 7.2.0 不加载我的 log4j

java - 这种并发相关的类怎么调用呢?是否有标准实现?

java - 尝试使用 scala Try 函数获取错误时出错

scala - 如何在 Scala 中组合 2 个迭代器?

java - JProgressBar 无法从 ActionEvent 正确显示