I can't add an element of type T
into a list List[T]
.
I tried with myList ::= myElement
but it seems it creates a strange object and accessing to myList.last
always returns the first element that was put inside the list. How can I solve this problem?

- 1,041
- 3
- 11
- 21

- 20,450
- 31
- 97
- 140
6 Answers
List(1,2,3) :+ 4
Results in List[Int] = List(1, 2, 3, 4)
Note that this operation has a complexity of O(n). If you need this operation frequently, or for long lists, consider using another data type (e.g. a ListBuffer).
-
Is it O(n) because it reverses the list, appends element to head, and then reverses it once more? Or is that O(2*n)? – Kevin Meredith Aug 09 '13 at 02:48
-
8There is no O(2*n), constant factors are ignored for asymptotic complexities. I think the `List` is converted to a `ListBuffer`, the element is appended, and the `ListBuffer` converted back (pretty much like `String` and `StringBuilder` in Java), but that's just a guess. – Landei Aug 09 '13 at 09:27
-
2It is O(n) because you have to traverse the list entirely in order to reach the last element pointer and be able to append the element making the last element pointer point to it. – Pikachu Sep 13 '13 at 01:56
-
44@pisaruk if that was the case, one could just maintain a pointer to the head and the tail. However, the [list in scala](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List) is immutable, meaning that to "modify" the last element of the list one needs to make a copy of it first. Its the copy that is O(n) - not the traversal of the list itself. – Nov 08 '13 at 19:44
-
2I believe it is O(n) simply because creates a brand new list – Raffaele Rossi Jul 01 '14 at 10:26
-
1@Landei there are no constant factors for asymptotic complexity classes, that does not preclude their use in describing asymptotic complexity =) – gal Sep 23 '14 at 20:47
-
@user289086 So does the cons operator :: have a complexity of O(n) as well? Can't the scala compiler optimize these operations the way e.g. haskell does? – cib Dec 16 '15 at 15:44
-
3The cons operator has complexity O(1), as it works on the "intended" side of the list. – Landei Dec 18 '15 at 09:42
-
BAD ANSWER. Does not append to list. Creates a whole new list instead. – aaa90210 Jun 12 '16 at 11:38
-
@cib No, the cons operator `::` returns a new `List` where the head is the new element and the tail is the old `List`. This can be done because `List`s are immutable, so Scala "knows" the original list won't change and therefore it can be reused as the tail of the new `List`. This can be done in O(1) because it doesn't depend on the size of the list. But you could ask why this isn't the case for appending at the end; can't the same reasoning be used? Well, no, because of how the `List` constructor is written: an immutable `List` in Scala is constructed out of a `head` and a `tail`. – Andres F. Jul 18 '18 at 19:48
-
Note the original list is not changed; it creates another list but not assigned to none. To change in place, either assign it to the old list, or use `ListBuffer` to append without assignment, like: `import scala.collection.mutable.ListBuffer \ var l = ListBuffer[String]() \ l += "a" \ l += "b"` – WesternGun Jan 02 '19 at 10:12
That's because you shouldn't do it (at least with an immutable list). If you really really need to append an element to the end of a data structure and this data structure really really needs to be a list and this list really really has to be immutable then do eiher this:
(4 :: List(1,2,3).reverse).reverse
or that:
List(1,2,3) ::: List(4)

- 16,775
- 6
- 44
- 55
-
Thanks a lot! That was exactly what I was searching for. I guess from your answer I shouldn't do that though... I'll revise my structure and see what can I do. Thanks again. – Masiar Oct 17 '11 at 13:19
-
6@Masiar use a Vector if you want immutability and efficient append. See the performance characteristics section in http://www.scala-lang.org/docu/files/collections-api/collections.html – Arjan Blokzijl Oct 17 '11 at 14:12
-
30The "build the list by prepending and then reverse it" is a useful pattern if you have many elements to add, but I don't think it's a good idea to apply it like you do in the case of adding a single element to an existing list. The "double reverse" trick rebuilds the list twice, while `:+`, inefficient as it may be, only rebuilds it once. – Nicolas Payette Oct 17 '11 at 21:54
Lists in Scala are not designed to be modified. In fact, you can't add elements to a Scala List
; it's an immutable data structure, like a Java String.
What you actually do when you "add an element to a list" in Scala is to create a new List from an existing List. (Source)
Instead of using lists for such use cases, I suggest to either use an ArrayBuffer
or a ListBuffer
. Those datastructures are designed to have new elements added.
Finally, after all your operations are done, the buffer then can be converted into a list. See the following REPL example:
scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer
scala> var fruits = new ListBuffer[String]()
fruits: scala.collection.mutable.ListBuffer[String] = ListBuffer()
scala> fruits += "Apple"
res0: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple)
scala> fruits += "Banana"
res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana)
scala> fruits += "Orange"
res2: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana, Orange)
scala> val fruitsList = fruits.toList
fruitsList: List[String] = List(Apple, Banana, Orange)

- 11,931
- 7
- 64
- 137
This is similar to one of the answers but in different way :
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)
scala> val y = x ::: 4 :: Nil
y: List[Int] = List(1, 2, 3, 4)

- 10,019
- 9
- 74
- 96

- 357
- 4
- 9
We can append or prepend two lists or list&array
Append:
var l = List(1,2,3)
l = l :+ 4
Result : 1 2 3 4
var ar = Array(4, 5, 6)
for(x <- ar)
{ l = l :+ x }
l.foreach(println)
Result:1 2 3 4 5 6
Prepending:
var l = List[Int]()
for(x <- ar)
{ l= x :: l } //prepending
l.foreach(println)
Result:6 5 4 1 2 3

- 10,019
- 9
- 74
- 96

- 57
- 5
-
2Yes, we can, but it would be a bad idea for all the reasons mentioned in the other answers. – jwvh Jun 08 '17 at 08:38
List is immutable in Scala
You can use MutableList
var l = scala.collection.mutable.MutableList(1,2,3)
l += 4

- 78
- 9