为什么Scala列表没有大小字段?

时间:2011-11-19 21:56:32

标签: java list scala data-structures

来自Java背景,我想知道为什么Scala中的List没有{Java}等效size的{​​{1}}字段。毕竟,使用大小字段,您将能够在常量时间内确定列表的大小,那么为什么大小字段会被删除?

(这个问题涉及Scala 2.8及更高版本中的新集合类。另外,我指的是不可变的LinkedList,而不是可变的{。}}。

6 个答案:

答案 0 :(得分:25)

不能说大小字段是掉落,因为没有大小的列表已经存在了50年,因为LISP无处不在,它们在ML和Haskell中也很常见,两者都有影响斯卡拉。

基本原因是list是递归结构。非空ListCons(head: A, tail: List[A]) - 除了Cons实际上称为::以允许方便的中缀表示法。您可以访问尾部(没有头元素的列表),这也是一个列表。这种情况几乎一直都在进行。因此,列表中的计数并不意味着只添加一个整数,而是添加与元素一样多的整数。这是可行的,但肯定不是免费的。

如果你与java的LinkedList进行比较,LinkedList有一个递归实现(基于Node,它或多或少像Cons,但在两个方向都有链接)。但是LinkedList不是Node,它拥有它们(并且保留它们的数量)。因此,虽然它具有递归实现,但您不能递归地处理它。您希望LinkedList的尾部作为LinkedList,您必须删除头部并更改列表,否则将所有尾部元素复制到新的LinkedList。因此,scala的List和java的LinkedList结构非常不同。

答案 1 :(得分:12)

因为保持这个字段

  1. 为所有列表添加内存开销;
  2. 在每个列表创建时添加少量时间开销。
  3. 在Java中,通常创建LinkedList,然后通过添加/删除元素来操作而不创建新列表;在Scala中,创建了许多List

    因此决定开销不值得。

答案 2 :(得分:8)

列表定义大小:

> List(1, 2, 3).size
res4: Int = 3

具有线性o(n)执行时间。如果你确实需要一个恒定的时间,你应该考虑提供恒定时间大小实现的可变ListBuffer

答案 3 :(得分:8)

O(n)复杂性的“劣势”并不像你想象的那么大。 Martin Odersky在一次演讲中提到(如果我没记错的话)在所有程序中用任何计算机语言创建的所有列表中有90%的大小为4或更小。 (这是在不变性和效率的背景下)

因此,对于大多数创建的列表来说,size的O(n)访问时间并不是一个很大的开销,而且正如其他人在这里提到的那样,节省内存不仅可以弥补这一点。

答案 4 :(得分:3)

您检查了length字段吗?

答案 5 :(得分:0)

我错过了什么吗?大小在那里:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.collection.immutable.List
import scala.collection.immutable.List

scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)

scala> a size
res0: Int = 3