Coming from a Java
background, I'm used to the common practice of dealing with collections: obviously there would be exceptions but usually code would look like:
public class MyClass {
private Set<String> mySet;
public void init() {
Set<String> s = new LinkedHashSet<String>();
s.add("Hello");
s.add("World");
mySet = Collections.unmodifiableSet(s);
}
}
I have to confess that I'm a bit befuddled by the plethora of options in Scala. There is:
scala.List
(and Seq
)scala.collections.Set
(and Map
)scala.collection.immutable.Set
(and Map
, Stack
but not List
)scala.collection.mutable.Set
(and Map
, Buffer
but not List
)scala.collection.jcl
So questions!
List
and Seq
defined in package scala
and not scala.collection
(even though implementations of Seq
are in the collection sub-packages)?unmodifiable
)?MultiMap
) only defined as mutable? (There is no immutable MultiMap
)?I've read Daniel Spiewak's excellent series on scala collections and am still puzzled by how one would actually use them in practice. The following seems slightly unwieldy due to the enforced full package declarations:
class MyScala {
var mySet: scala.collection.Set[String] = null
def init(): Unit = {
val s = scala.collection.mutable.Set.empty[String]
s + "Hello"
s + "World"
mySet = scala.collection.immutable.Set(s : _ *)
}
}
Although arguably this is more correct than the Java version as the immutable collection cannot change (as in the Java case, where the underlying collection could be altered underneath the unmodifiable
wrapper)
Why are List and Seq defined in package scala and not scala.collection (even though implementations of Seq are in the collection sub-packages)?
Because they are deemed so generally useful that they are automatically imported into all programs via synonyms in scala.Predef.
What is the standard mechanism for initializing a collection and then freezing it (which in Java is achieved by wrapping in an unmodifiable)?
Java doesn't have a mechanism for freezing a collection. It only has an idiom for wrapping the (still modifiable) collection in a wrapper that throws an exception. The proper idiom in Scala is to copy a mutable collection into an immutable one - probably using :_*
Why are some collection types (e.g. MultiMap) only defined as mutable? (There is no immutable MultiMap)?
The team/community just hasn't gotten there yet. The 2.7 branch saw a bunch of additions and 2.8 is expected to have a bunch more.
The following seems slightly unwieldy due to the enforced full package declarations:
Scala allows import aliases so it's always less verbose than Java in this regard (see for example java.util.Date and java.sql.Date - using both forces one to be fully qualified)
import scala.collection.{Set => ISet}
import scala.collection.mutable.{Set => MSet}
class MyScala {
var mySet: ISet[String] = null
def init(): Unit = {
val s = MSet.empty[String]
s + "Hello"
s + "World"
mySet = Set(s : _ *)
}
}
Of course, you'd really just write init as def init() { mySet = Set("Hello", "World")}
and save all the trouble or better yet just put it in the constructor var mySet : ISet[String] = Set("Hello", "World")