Given two lists a
and b
, what's the difference between a ::: b
and a ++ b
? I suspected one of these operators would simply call the other, but in fact, the implementations look completely different:
def :::[B >: A](prefix: List[B]): List[B] =
if (isEmpty) prefix
else if (prefix.isEmpty) this
else (new ListBuffer[B] ++= prefix).prependToList(this)
override def ++[B >: A, That](that: GenTraversableOnce[B])
(implicit bf: CanBuildFrom[List[A], B, That]): That = {
val b = bf(this)
if (b.isInstanceOf[ListBuffer[_]])(this ::: that.seq.toList).asInstanceOf[That]
else super.++(that)
}
From a usage perspective, should I prefer a ::: b
or a ++ b
? From an implementation perspective, is there a specific reason why one of these operators doesn't simply call the other?
list is a global name that may be overridden during runtime. list() calls that name. [] is always a list literal.
The difference is in the types that they accept. ::: only accepts a List . ++ accepts is a range of types from [B >: A, That] meaning that ++ will accept a type whose lower bound is List and upper bound is GenTraversableOnce[B] and types in between.
Strings can only consist of characters, while lists can contain any data type. Because of the previous difference, we cannot easily make a list into a string, but we can make a string into a list of characters, simply by using the list() function.
List is used to collect items that usually consist of elements of multiple data types. An array is also a vital component that collects several items of the same data type. List cannot manage arithmetic operations. Array can manage arithmetic operations.
The difference is in that you can only use :::
on 2 lists -- this operation is only available on the List
datatype. Since lists are sequences, it acts as a concatenation operators for lists.
The ++
method is more general - it allows creating a union of any two collections. That may be two sets, in which case it acts as a union, or two sequences in which case it acts as a concatenation.
There is no semantic difference between ++
and :::
for 2 lists -- :::
is the variant of ++
for functional lists that should look more familiar to functional programmers.
The if
statement you see in the ++
implementation is an optimization -- if both this
collection and that
collection are lists, just use the list concatenation operator :::
to add the two lists together. Otherwise, use the generic implementation of ++
that adds all the elements of this
and that
collection to an appropriate builder for the type That
.
So, the relevant difference for lists is performance -- for functional lists you don't need to traverse the second list as a generic ++
implementation would - only the nodes of the first list need to be reinstantiated to create a new functional list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With