当前位置:  开发笔记 > 编程语言 > 正文

Scala集合标准实践

如何解决《Scala集合标准实践》经验,为你挑选了2个好方法。

来自一个Java背景,我已经习惯了处理集合的常见做法:显然会有异常,但通常代码看起来像:

public class MyClass {
  private Set mySet;

  public void init() {
    Set s = new LinkedHashSet();
    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

所以问题!

    为什么List并且Seq在包中定义scala而不是 scala.collection(尽管实现Seq是在集合子包​​中)?

    初始化集合然后冻结它的标准机制是什么(在Java中是通过包装来实现的unmodifiable)?

    为什么某些集合类型(例如MultiMap)仅定义为可变?(没有不可改变的MultiMap)?

我读过Daniel Spiewak 关于scala集合的精彩系列,我仍然对如何在实践中实际使用它们感到困惑.由于强制完整的包声明,以下内容似乎有点笨拙:

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包装器下面改变)



1> James Iry..:

为什么在包scala中定义List和Seq而不是scala.collection(即使Seq的实现在集合子包​​中)?

因为它们被认为非常有用,所以它们会通过scala.Predef中的同义词自动导入到所有程序中.

初始化集合然后冻结它的标准机制是什么(在Java中是通过以不可修改的形式包装来实现的)?

Java没有冻结集合的机制.它只有一个成语,用于将(仍然可修改的)集合包装在一个抛出异常的包装器中.Scala中正确的习惯用法是将可变集合复制到不可变集合中 - 可能使用:_*

为什么有些集合类型(例如MultiMap)只被定义为可变?(没有不可变的MultiMap)?

团队/社区还没有到达那里.2.7分支看到了一堆补充,2.8预计会有更多.

由于强制完整的包声明,以下内容似乎有点笨拙:

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")



2> andrewf..:

可变集合偶尔也很有用(尽管我同意你应该首先考虑不可变集合).如果使用它们,我倾向于写

import scala.collection.mutable

在文件的顶部,(例如):

val cache = new mutable.HashMap[String, Int]

在我的代码中.这意味着你只需要编写"mutable.HashMap",而不是scala.collection.mutable.HashMap".作为上面提到的评论员,您可以在导入中重新映射名称(例如,"import scala.collection.mutable.{HashMap => MMap}"),但是:

    我不想破坏名字,所以我更清楚地使用哪些类,以及

    我很少使用'mutable',因为在我的源代码中使用"mutable.ClassName"并不是一个不适当的负担.

(另外,我是否可以回应'避免空值'评论.它使代码更加健壮和易于理解.我发现我甚至不必像你期望的那样使用Option.)

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有