Please check this
import scala.collection.mutable.LinkedList
var l = new LinkedList[String]
l append LinkedList("abc", "asd")
println(l)
// prints
// LinkedList()
but
import scala.collection.mutable.LinkedList
var l = new LinkedList[String]
l = LinkedList("x")
l append LinkedList("abc", "asd")
println(l)
// prints
// LinkedList(x, abc, asd)
Why does the second code snippet works but the first one doesnt? This is on Scala 2.10
This is the first method we use to append Scala List using the operator “:+”. The syntax we use in this method is; first to declare the list name and then use the ':+' method rather than the new element that will be appended in the list. The syntax looks like “List name:+ new elements”.
In Set, We can only add new elements in mutable set. +=, ++== and add() method is used to add new elements when we are working with mutable set in mutable collection and += is used to add new elements when we are working with mutable set in immutable collection.
The documentation says If this is empty then it does nothing and returns that. Otherwise, appends that to this.
. That is exactly, what you observed. If you really need a mutable list, I would suggest you to use scala.collection.mutable.ListBuffer
instead, with it you can do
val lb = new ListBuffer[Int]
scala> lb += 1
res14: lb.type = ListBuffer(1)
scala> lb
res15: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1)
scala> lb ++= Seq(1,2,3)
res17: lb.type = ListBuffer(1, 1, 2, 3, 1, 2, 3)
scala> lb
res18: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 1, 2, 3, 1, 2, 3)
As I understand it is related to First/Last (Nil
) element in the list (if list is empty Nil
is first and last element at the same time).
LinkedList (still) follows "primitive charm" strategy. So it does not try to add/append new data to/after Nil
, to have possible result like this: {Nil, newElement}. (After all Nil
should be last element)
Of course it could check if
list is empty then put addingList
to the beginning and Nil
to the end. But this would be "too smart", I guess.
But, anyway append()
returns "expecting" result Like this:
val addingList = new LinkedList[String]("a", "b")
val result = emptyList append addingList
result = {"a", "b"}.
In this case it returns 'addingList' itself, and/but does not change initial list.
If we try to assign newElement to the next
ref:
emptyList.next = LinkedList("whatever")
As result we would have emtyList changed like this:
LinkedList(null, whatever)
I.e. it creates fist element as null, since we have used next()
assigning new/next element to it. So it moves Nil to the end, because first element which is null, has next reference to new element we added (addingElelement
).
Because
"the "emptyList" is also the "head" link"
and head in our case head is Nil
, but Nill
can not have next, so it has to create new first element (which is has null value) with next() referece to our new addingElelement
.
Personally I find it "too much primitive" and not "so much elegant". But it depends, I guess.
Task oriented story:
For my initial task (why I start thinking about this 'strange' list behaviour [even though it's mutable]) -- I wanted to use mutable list for a class/object called Dictionary
which would keep Words
in it (dictionary by default has not any words). And I would have methods like addWord(wod:String)
for adding new words. For now my implementation will be changed (I'm not going to use this LinkedList
, but rather MutableList
. It seems it is more mutable than previous one):
object Dictionary {
val words = new mutable.MutableList[Word]();
def addWord(word: Word): Unit = {
words += word;
}
}
But possible implementation could be like this:
object Dictionary {
var words = new mutable.LinkedList[Word]();
def addWord(word: Word): Unit = {
if (words.isEmpty) {
words = words append( mutable.LinkedList[Word](word) ) // rely on append result
} else {
words append( mutable.LinkedList[Word](word) )
}
}
}
But then I have to use var
instead of val
, and I should transform every new Word to LinkedList
, and my logic became more complicated.
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