Java 为什么';Scala列表是否有大小字段?

Java 为什么';Scala列表是否有大小字段?,java,list,scala,data-structures,Java,List,Scala,Data Structures,来自Java背景,我想知道为什么Scala中的List没有一个与Java等价的LinkedList类似的size字段。毕竟,有了大小字段,您就可以在固定时间内确定列表的大小,那么为什么要删除大小字段呢 (这个问题指的是Scala 2.8及更高版本中的新集合类。另外,我指的是不可变的列表,而不是可变的。) > List(1, 2, 3).size res4: Int = 3 具有线性o(n)执行时间。如果你真的需要一个固定的时间,你应该考虑可变的 ListBuffer ,它提供了一个固定的

来自Java背景,我想知道为什么Scala中的
List
没有一个与Java等价的
LinkedList
类似的
size
字段。毕竟,有了大小字段,您就可以在固定时间内确定列表的大小,那么为什么要删除大小字段呢

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

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

具有线性o(n)执行时间。如果你真的需要一个固定的时间,你应该考虑可变的<代码> ListBuffer <代码>,它提供了一个固定的时间长度实现。

,因为维护这个字段将

  • 增加所有列表的内存开销
  • 在每次创建列表时都会增加少量的时间开销
  • 在Java中,通常会创建一个
    LinkedList
    ,然后通过添加/删除元素在不创建新列表的情况下进行操作;在Scala中,创建了许多
    列表


    因此,我们认为开销是不值得的。

    不能说大小字段被删除了,因为没有大小的列表自LISP以来已经存在了50年,它们无处不在,在ML和Haskell中也很常见,这两个字段在scala中都很有影响力

    基本原因是列表是一种递归结构。非空的
    列表
    Cons(head:A,tail:List[A])
    ——除了它实际上被称为
    ,以便使用方便的中缀符号。您可以访问尾部(不带head元素的列表),这也是一个列表。这几乎一直都在进行。因此,将计数包含在列表中并不意味着只添加一个整数,而是添加与元素数量相同的整数。这是可行的,但肯定不是免费的


    如果与java的
    LinkedList
    相比,
    LinkedList
    有一个递归实现(基于节点,它或多或少类似于Cons,但具有双向链接)。但LinkedList不是节点,它拥有它们(并保持它们的计数)。因此,虽然它有一个递归实现,但不能递归地处理它。如果希望LinkedList的尾部作为LinkedList,则必须删除头部并更改列表,或者将所有尾部元素复制到新的LinkedList。所以scala的
    列表
    和java的
    链接列表
    是非常不同的结构。

    我遗漏了什么吗?尺寸如下:

    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
    
    O(n)复杂性的“缺点”并不像你想象的那么大。Martin Odersky在一次演讲中提到(如果我没记错的话),在任何计算机语言的所有程序中创建的所有列表中,有90%的列表大小不超过4。(这是在不变性和效率的背景下进行的)


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

    它是Java中的
    size()。Scala列表没有这样的字段,这是有充分理由的,但这使得访问长度为O(n)。“python dude”来自Java背景?python不是指语言,是吗?@huynhjl:我不能有多个背景吗?;-)@huynhjl:不。这意味着他是一条雄性python。
    length
    是一种遍历整个列表的方法,因此具有
    O(n)
    复杂性。OP询问为什么没有具有固定时间访问权限的
    长度
    字段。@Udo保持:您的链接来自Scala 2.7.7,我对此没有经验。我的问题基于Scala 2.9+,特别是《Scala编程》一书第二版,第16章指出,确定列表的长度与元素的数量是线性的。也有长度,为2.9。你也可以在那里找到与长度相等的大小。我想这个问题是指不可变列表,这是scala中的默认列表。它没有长度字段这是哪个版本的Scala?在2.8之前或之后?至少在2.8之后。看:这是恒定的时间吗?上面写着“相当于长度”,事实上你是对的。列表具有线性o(n)大小执行时间我们可以在代码上看到:FWIW immutable
    Vector
    是一种索引数据结构,具有高效的
    长度
    (在其他索引操作中)-因此,如果没有其他好的理由,可以选择牺牲不变性。事实上,添加
    size
    字段会将cons的大小从8字节增加到16字节,因为对象是以8字节的倍数分配的。确切地说,这是一个o(n)大小的实现。主题是LinkedList java实现有一个大小字段,在固定时间内重新计算大小。所以每次应用Cons时,它都知道尾部的大小,所以可以增加1并将其写入特定字段。像
    Cons(head:A,tail:List[A]){override val size:Int=tail.size+1}
    。这是可能的,但可能会被视为空间太大。