Scala Collections inconsistencies

风流意气都作罢 提交于 2019-12-06 03:02:31

问题


Why is there a lack of consistency between Sets and Lists in Scala Collections API?

For example, there is immutable Set, but also a mutable one. If I want to use the latter, I can simply do this:

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

However, there is no mutable List, per se. If I want to write a similar code snippet using Lists, which data structure to use? LinkedList sounds as a good candidate, because it is mutable, but has no += method defined. ListBuffer seems to satisfy the requirements, but it is not a list.

After reading 2.8 Collections docs I come to the conclusion MutableList is probably the best fit.

I still somehow wish there was scala.collection.mutable.List.


回答1:


The reason for this is that Java has co-opted the functional List type to mean something that it is not (i.e. java.util.List is not a list).

It probably makes no sense for a functional programming language to have a mutable List as such a type is an oxymoron. Hence ListBuffer or ArrayBuffer. Or just use IndexedSeq, of which there are mutable and immutable implementations




回答2:


The sequence/list analogue of Set in Scala's collection libraries is Seq. List is just a particular, immutable implementation of Seq, as is Vector. ArrayBuffer or ListBuffer are typical implementations of mutable.Seq.




回答3:


ArraySeq may be what you are looking for, except += is exceptionally slow. You could also use a java.util.ArrayList and import collection.JavaConversions._

It seems Scala lacks a good mutable List-like collection with constant time index (like ArrayList for java).

In any case, note that "List" refers to exactly the type "scala.immutable.List". Therefore Seq (or some other more abstract collection type), is the type you should expect in methods rather than "List" if you want to generalize over immutable/mutable collections.

More ideal is requring an IndexedSeq, which sort of means that the index operation is performant for that collection. However, I'm not sure ListBuffer falls into that category.




回答4:


Because Set is just a trait -- it is abstract and requires an implementation. So one can speak of classes which are mutable.Set or immutable.Set.

Meanwhile, List is a class, an implementation of the (abstract) trait immutable.LinearSeq. There can never be any other class which is also a List. You'll find out, however, that there is a mutable.LinearSeq trait.

In Java terms, you are comparing interfaces with classes -- they are distinct.




回答5:


Don't forget scala.collection.mutable.{LinkedList,DoubleLinkedList}. They are mutable, and they are LinearSeq. Mutation is a little weird--you can modify the head by assigning to the elem reference, and the tail by assigning to the next reference.

For example, this loop changes all negative values to zero.

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 
}

This loop removes every second element from the list.

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

I am not suggesting that these are any better than the immutable List. I am just pointing out that Scala has mutable lists that look fairly similar to what you have seen in your data structures class.



来源:https://stackoverflow.com/questions/4092214/scala-collections-inconsistencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!