In Java terms, Scala's
Seq
would be Java's List
, and Scala's List
would be Java's LinkedList
.
Note that
Nil is equivalent to List.empty[Nothing], where Nothing is the subtype of all other types.
Seq
is a trait
, which is equivalent to Java's interface
, but with the equivalent of up-and-coming defender methods. Scala's List
is an abstract class that is extended by Nil
and ::
, which are the concrete implementations of List
. For Seq, the "cons" operator is +: instead of ::Nil is equivalent to List.empty[Nothing], where Nothing is the subtype of all other types.
So, where Java's
List
is an interface
, Scala's List
is an implementation.
Beyond that, Scala's
List
is immutable, which is not the case of LinkedList
. In fact, Java has no equivalent to immutable collections (the read only thing only guarantees the new object cannot be changed, but you still can change the old one, and, therefore, the "read only" one).
Scala's
List
is highly optimized by compiler and libraries, and it's a fundamental data type in functional programming. However, it has limitations and it's inadequate for parallel programming. These days, Vector
is a better choice than List
, but habit is hard to break.Seq
is a good generalization for sequences, so if you program to interfaces, you should use that. Note that there are actually three of them: collection.Seq
, collection.mutable.Seq
and collection.immutable.Seq
, and it is the latter one that is the "default" imported into scope.
There's also
Seq represents collections that have a sequential ordering. We can use the apply method to index into the collection by its ordering. If the order in which things are placed into a collections is important and duplicates should be allowed, then the Seq trait should be required. Seq tends to be used frequently in abstract methods when the algorithms are usually targeted at one of its two subclasses.
Using the Seq trait allows the computation of sliding windows over the data.
scala> Seq(2, 1, 30, -2).sliding(2).map(_.sum).toList
scala> val seq = Seq("a","b")
seq: Seq[String] = List(a, b)
When you use the Seq.apply method on the companion object, it constructs a List, because Seq is a trait, not a concrete class.
While it's still common to construct lists when appropriate, it is not recommended that methods be defined to take List arguments or return List values. Instead, use Seq, so that an instance of any subtype of Seq can be used, including List and Vector.
Reference:
http://stackoverflow.com/questions/10866639/scala-difference-between-a-seq-and-a-list
GenSeq
and ParSeq
. The latter methods run in parallel where possible, which the former is parent to Seq
and ParSeq
both, being a suitable generalization for when parallelism of a code doesn't matter. They are both relatively newly introduced, so people doesn't use them much yet.Seq represents collections that have a sequential ordering. We can use the apply method to index into the collection by its ordering. If the order in which things are placed into a collections is important and duplicates should be allowed, then the Seq trait should be required. Seq tends to be used frequently in abstract methods when the algorithms are usually targeted at one of its two subclasses.
Using the Seq trait allows the computation of sliding windows over the data.
scala> Seq(2, 1, 30, -2).sliding(2).map(_.sum).toList
scala> val seq = Seq("a","b")
seq: Seq[String] = List(a, b)
When you use the Seq.apply method on the companion object, it constructs a List, because Seq is a trait, not a concrete class.
While it's still common to construct lists when appropriate, it is not recommended that methods be defined to take List arguments or return List values. Instead, use Seq, so that an instance of any subtype of Seq can be used, including List and Vector.
Reference:
http://stackoverflow.com/questions/10866639/scala-difference-between-a-seq-and-a-list
No comments:
Post a Comment