问题
Say, I have a sequence of strings as an input and I want to get a new immutable Seq which consists of elements of the input and an item "c". Here are two methods that I've discovered to be working:
assert(Seq("a", "b", "c") == Seq("a", "b") ++ Seq("c"))- the problem with this one is that it seems that instantiating a temporary sequence (Seq("c")) just for the sake of the operation is rendundant and will result in overheadassert(Seq("a", "b", "c") == List("a", "b") ::: "c" :: Nil)- this one restricts the type of input collection to be aList, soSeq("a", "b") ::: "c" :: Nilwon't work. Also it seems that instantiating aNilmay aswell result in overhead
My questions are:
- Is there any other way of performing this operation?
- Which one is better?
- Isn't
Seq("a", "b") ::: Nilnot being allowed a flaw of Scala's developers?
回答1:
Use the :+ (append) operator to create a new Seq using:
val seq = Seq("a", "b") :+ "c"
// seq is now ("a","b","c")
Note: :+ will create a new Seq object.
If you have
val mySeq = Seq("a","b")
and you will call
mySeq :+ "c"
mySeq will still be ("a","b")
Note that some implementations of Seq are more suitable for appending than others. List is optimised for prepending. Vector has fast append and prepend operations.
::: is a method on List which requires another List as its parameter - what are the advantages that you see in it accepting other types of sequence? It would have to convert other types to a List. If you know that List is efficient for your use case then use ::: (if you must). If you want polymorphic behaviour then use the generic ++.
There's no instantiation overhead to using Nil; you don't instantiate it because it's a singleton.
来源:https://stackoverflow.com/questions/8295597/adding-an-item-to-an-immutable-seq