5

为什么 Scala Collections API 中的 Set 和 List 之间缺乏一致性?

例如,有不可变的 Set,但也有可变的。如果我想使用后者,我可以简单地这样做:

val set = Set[A]()
set += new A

但是,本身没有可变列表。如果我想使用 Lists 编写类似的代码片段,使用哪种数据结构?LinkedList 听起来不错,因为它是可变的,但没有定义 += 方法。ListBuffer 似乎满足要求,但它不是一个列表。

阅读 2.8 Collections 文档后,我得出结论 MutableList 可能是最合适的。

我仍然以某种方式希望有 scala.collection.mutable.List。

4

5 回答 5

20

这样做的原因是Java 已经选择了函数 List类型来表示它不是的东西(即java.util.List不是列表)。

对于函数式编程语言来说,拥有一个可变 List类型可能是没有意义的,因为这种类型是矛盾的。因此ListBufferArrayBuffer。或者只是 use IndexedSeq,其中有可变和不可变的实现

于 2010-11-03T22:56:43.847 回答
9

SetScala 集合库中的序列/列表类似物是Seq. List只是 的一个特定的、不可变的实现Seq,就像Vector. ArrayBuffer或者ListBuffermutable.Seq.

于 2010-11-05T11:49:47.737 回答
3

ArraySeq 可能是您正在寻找的,除了 += 非常慢。您还可以使用 java.util.ArrayList 并导入 collection.JavaConversions._

似乎 Scala 缺乏具有恒定时间索引的良好的可变 List 类集合(如 java 的 ArrayList)。

在任何情况下,请注意“List”正是指“scala.immutable.List”类型。因此,如果您想泛化不可变/可变集合,Seq(或其他一些更抽象的集合类型)是您应该在方法中而不是“List”中期望的类型。

更理想的是要求 IndexedSeq,这在某种程度上意味着索引操作对于该集合是有效的。但是,我不确定 ListBuffer 是否属于该类别。

于 2010-11-03T22:51:24.903 回答
2

因为Set只是一个特征——它是抽象的并且需要一个实现。所以可以说是mutable.Set或的类immutable.Set

同时,List是一个类,是(抽象)特征的实现immutable.LinearSeq。永远不可能有任何其他类也是List. 然而,你会发现有一个特点mutable.LinearSeq

在 Java 术语中,您将接口与类进行比较——它们是不同的。

于 2010-11-04T23:47:16.293 回答
0

别忘了scala.collection.mutable.{LinkedList,DoubleLinkedList}。它们是可变的,而且它们是LinearSeq. 突变有点奇怪——你可以通过分配给参考来修改头部,通过分配给elem参考来修改尾部next

例如,此循环将所有负值更改为零。

val lst = collection.mutable.LinkedList(1, -2, 7, -9)
var cur = lst
while (cur != Nil) { 
  if (cur.elem < 0) cur.elem = 0
  cur = cur.next 
}

此循环从列表中删除每隔一个元素。

var cur = lst
while (cur != Nil && cur.next != Nil) { 
  cur.next = cur.next.next
  cur = cur.next 
}

我并不是说这些比不可变列表更好。我只是指出 Scala 具有可变列表,看起来与您在数据结构类中看到的非常相似。

于 2011-07-19T02:06:11.273 回答