Scala has both a mutable and an immutable Map ,
but it has only an immutable List.
If you want a mutable List you need a ListBuffer.
I don't understand why this is so.
Any one knows?.
You can choose between these:
scala.collection.mutable.DoubleLinkedList
scala.collection.mutable.LinkedList
scala.collection.mutable.ListBuffer
scala.collection.mutable.MutableList
So, yes, Scala has mutable lists :-)
I hope that this article may be of some use to you. The diagram at the bottom of the page is particularly useful in providing the mutable and immutable classes.
http://www.scala-lang.org/docu/files/collections-api/collections_1.html
There is a mutable List, but it is called Buffer. The article linked by Graham goes into more depth, but I thought there should be a specific answer to the question as well.
Map is a trait -- like Java's interface --, while List is a class, a concrete implementation of a Seq. There are mutable and immutable Seq, just like for Map.
This may be confusing to Java programmers because, in Java, List is an interface, whose (main) implementations are ArrayList and LinkedList. Alas, Java naming is atrocious. First, ArrayList is not a List by any stretch of imagination. Also, the interface has methods that are not really related to any traditional list.
So, if you want mutable/immutable equivalence, look to concrete subclass implementations of Seq.
Related
What is the equivalent of java.util.Collection? I first thought Seq is the way to go, but actually it's an ordered set of elements. I mean we have a numeration of elements.
Collection Hierarcy
Traversable is on top above iterable
The picture above is very good looking, but it is not helpful at all in answering the question. (It may be helpful as general reference for other purposes, but not for this purpose.) It is even missing some very important interfaces. So, here is some good old text to try and clear out the confusion:
The Scala equivalent to java.util.Collection is scala.collection.Iterable, despite the mismatch in the name.
You see, scala.collection.Iterable offers the basic functionality of a Java Collection: it has an iterator and a size.
Apparently, what Java calls Iterable Scala calls it Traversable, and then what Java calls Collection Scala calls it Iterable.
I'm new to scala(just start learning it), but have figured out smth strange for me: there are classes Array and List, they both have such methods/functions as foreach, forall, map etc. But any of these methods aren't inherited from some special class(trait). From java perspective if Array and List provide some contract, that contract have to be declared in interface and partially implemented in abstract classes. Why do in scala each type(Array and List) declares own set of methods? Why do not they have some common type?
But any of these methods aren't inherited from some special class(trait)
That simply not true.
If you open scaladoc and lookup say .map method of Array and List and then click on it you'll see where it is defined:
For list:
For array:
See also info about Traversable and Iterable both of which define most of the contracts in scala collections (but some collections may re-implement methods defined in Traversable/Iterable, e.g. for efficiency).
You may also want to look at relations between collections (scroll to the two diagrams) in general.
I'll extend om-nom-nom answer here.
Scala doesn't have an Array -- that's Java Array, and Java Array doesn't implement any interface. In fact, it isn't even a proper class, if I'm not mistaken, and it certainly is implemented through special mechanisms at the bytecode level.
On Scala, however, everything is a class -- an Int (Java's int) is a class, and so is Array. But in these cases, where the actual class comes from Java, Scala is limited by the type hierarchy provided by Java.
Now, going back to foreach, map, etc, they are not methods present in Java. However, Scala allows one to add implicit conversions from one class to another, and, through that mechanism, add methods. When you call arr.foreach(println), what is really done is Predef.refArrayOps(arr).foreach(println), which means foreach belongs to the ArrayOps class -- as you can see in the scaladoc documentation.
Could someone please help me understand Scala's various "Like" traits in the collection API. I've been reading over and trying to compare each without luck. I think I can see that Map for example, extends MapLike - adding 2 concrete methods. But this begs the question of why do this at all? Why not just have 1 Map trait in the Collections API instead of Map and MapLike?
Thank you!
The best source for these details is Martin Odersky and Lex Spoon's "What's New in Scala 2.8: The Architecture of Scala Collections":
The Scala collection library avoids code duplication and achieves the
"same-result-type" principle by using generic builders and traversals
over collections in so-called implementation traits. These traits
are named with a Like suffix; for instance, IndexedSeqLike is the
implementation trait for IndexedSeq, and similarly,
TraversableLike is the implementation trait for Traversable.
Collection classes such as Traversable or IndexedSeq inherit all
their concrete method implementations from these traits.
Implementation traits have two type parameters instead of one for
normal collections. They parameterize not only over the collection's
element type, but also over the collection's representation type,
i.e., the type of the underlying collection, such as Seq[I] or List[T]...
The whole article is extremely useful if you want to integrate your own collection classes with the Collections API, or if you just want a deeper understanding of how the library works.
I need something to store a LIFO. No need for traversing and other functions except for push and pop.
I've found special class in scala collection for creating a stack. But it lacks Nil object in pattern matching and other handy scala idioms. Immutable lists suit well at first glance, they have cons for construction and for extraction and that is all needed from LIFO.
Is there any reason behind scala.collection.immutable.Stack existence? Why I should prefer to use it, what are use cases to show its benefits?
From the API documentation:
Note: This class exists only for historical reason and as an analogue
of mutable stacks. Instead of an immutable stack you can just use a
list.
And in a little more detail:
Immutable stacks are used rarely in Scala programs because their
functionality is subsumed by lists: A push on an immutable stack is
the same as a :: on a list and a pop on a stack is the same as a tail on
a list.
So to answer your questions:
Yes, there's a reason for its existence.
No, you shouldn't prefer it over lists.
Trait Traversable has methods such as toList, toMap, ToSeq. Given that List, Map, Seq are subclasses of Traversable, this creates a circular dependency, which is generally not a desirable design pattern.
I understand that this is constrained to the collections library and it provides some nice transformation methods.
Was there any alternative design considered? Such as a "utility" class, or adding the conversion methods to Predef?
Say I want to add a new class: class RandomList extends List {...}. It would be nice to have a method toRandomList available for all Traversable classes, but for that I would need to "pimp my library" with an implicit on Traversable? This seems a bit of an overkill. With a utility class design, I could just extend that class (or Predef) to add my conversion method. What would be the recommended design here?
An alternative and extensible approach would be to[List], to[RandomList].
It's a bit tricky to add this with implicits, though. https://gist.github.com/445874/2a4b0bb0bde29485fec1ad1a5bbf968df80f2905
To add a toRandomClass you'd have to resort to a pimp my library pattern indeed. However, why do you think that is overkill? The overhead is negligible. And it wouldn't work extending an utility class -- why would Scala look into your new class for that method? Not to mention that you'd have to instantiate such a class to be able to access its methods.
There is no circular dependency here.
Circular dependency is what happens when there are a few independent components which refer to each other.
Scala standard library is one component. Since it is built always in one step there is no problem.
You are right. Let's remove toString from the String class...