At SO, I have seen questions that compare Array with Seq, List with Seq and Vector with well, everything. I do not understand one thing though. When should I actually use a Seq
over any of these? I understand when to use a List
, when to use an Array
and when to use a Vector
. But when is it a good idea to use Seq
rather than any of the above listed collections? Why should I use a trait
that extends Iterable
rather than all the concrete classes listed above?
You usually should use Seq as input parameter for method or class, defined for sequences in general (just general, not necessarily with generic):
def mySort[T](seq: Seq[T]) = ...
case class Wrapper[T](seq: Seq[T])
implicit class RichSeq[T](seq: Seq[T]) { def mySort = ...}
So now you can pass any sequence (like Vector
or List
) to mySort
.
If you care about algorithmic complexity - you can specialize it to IndexedSeq
(quick random element access) or LinearSeq
(fast memory allocation). Anyway, you should prefer most top-level class if you want your function to be more polymorphic has on its input parameter, as Seq
is a common interface for all sequences. If you need something even more generic - you may use Traversable
or Iterable
.
The principal here is the same as in a number of languages (E.g. in Java should often use List instead of ArrayList, or Map instead of HashMap). If you can deal with the more abstract concept of a Seq, you should, especially when they are parameters to methods.
2 main reasons that come to mind:
1) reuse of your code. e.g. if you have a method that takes a foo(s:Seq), it can be reused for lists and arrays.
2) the ability to change your mind easily. E.g. If you decide that List is working well, but suddenly you realise you need random access, and want to change it to an Array, if you have been defining List everywhere, you'll be forced to change it everywhere.
Note #1: there are times where you could say Iterable over Seq, if your method supports it, in which case I'd inclined to be as abstract as possible.
Note #2: Sometimes, I might be inclined to not say Seq (or be totally abstract) in my work libraries, even if I could. E.g. if I were to do something which would be highly non-performant with the wrong collection. Such as doing Random Access - even if I could write my code to work with a List, it would result in major inefficiency.
© 2022 - 2024 — McMap. All rights reserved.