Reputation: 2596
In the documentation of +:
method in ArraySeq
said that
A copy of the sequence with an element prepended.
Is there a way to prepend an element without copying the whole ArraySeq
?
Upvotes: 1
Views: 697
Reputation: 29155
This is how ArraySeq
works.
AFAIK there is no other built in option available.
Means, to adjust the size it has to return new copy :(
scala> val a = List(1)
a: List[Int] = List(1)
scala> val b = a :+ 2
b: List[Int] = List(1, 2)
scala> println(a)
List(1)
Doc says:
abstract def +:(elem: A): ArraySeq[A] [use case] A copy of the array sequence with an element prepended. elem the prepended element returns a new collection of type That consisting of elem followed by all elements of this array sequence. Definition Classes GenSeqLike
Similar function is there in ArrayBuffer as well. It also copies to create new one. Below are the snippets for better understanding...
snippet 1:
/** Prepends a single element to this buffer and returns
* the identity of the buffer. It takes time linear in
* the buffer size.
*
* @param elem the element to append.
* @return the updated buffer.
*/
def +=:(elem: A): this.type = {
ensureSize(size0 + 1)
copy(0, 1, size0)
array(0) = elem.asInstanceOf[AnyRef]
size0 += 1
this
}
Snippet2:
/** Inserts new elements at the index `n`. Opposed to method
* `update`, this method will not replace an element with a
* one. Instead, it will insert a new element at index `n`.
*
* @param n the index where a new element will be inserted.
* @param seq the traversable object providing all elements to insert.
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
def insertAll(n: Int, seq: Traversable[A]) {
if (n < 0 || n > size0) throw new IndexOutOfBoundsException(n.toString)
val xs = seq.toList
val len = xs.length
ensureSize(size0 + len)
copy(n, n + len, size0 - n)
xs.copyToArray(array.asInstanceOf[scala.Array[Any]], n)
size0 += len
}
Upvotes: 1
Reputation: 2101
Even though ArraySeq is a mutable collection, certain member methods of this collection will return a copy of the collection and not do "in place" transformation. From the scala doc collections overview
A collection in package scala.collection.mutable is known to have some operations that change the collection in place. So dealing with mutable collection means you need to understand which code changes which collection when.
So, its possible that mutable collections will have some methods that will return copies of the original collection.
On the other hand, its guaranteed that all operations on collections in the scala.collection.immutable package will return copies of the original collection.
Upvotes: 1
Reputation: 369430
You can't. Quoting from the Collections Overview (bold emphasis mine):
Array sequences are mutable sequences of fixed size which store their elements internally in an
Array[Object]
. They are implemented in Scala by classArraySeq
.
Prepending changes the size, ergo it is not possible to prepend to an ArraySeq
.
They are very similar to Array
s, which are of course also mutable and have a fixed size.
If you want to change the size, you need a *Builder
or a *Buffer
, in this case, an ArrayBuffer
, which does have a +=:
method for prepending.
Upvotes: 1