For 4 or fewer elements, something like this works (or at least compiles):

import scala.collection.immutable.Map;

Map<String,String> HAI_MAP = new Map4<>("Hello", "World",
                                        "Happy", "Birthday",
                                        "Merry", "XMas",
                                        "Bye", "For Now");

For a 5th element I could do this:

Map<String,String> b = HAI_MAP.$plus(new Tuple2<>("Later", "Aligator"));

But I want to know how to initialize an immutable map with 5 or more elements and I'm flailing in Type-hell.

Partial Solution

I thought I'd figure this out quickly by compiling what I wanted in Scala, then decompiling the resultant class files. Here's the scala:

object JavaMapTest {
  def main(args: Array[String]) = {
    val HAI_MAP = Map(("Hello", "World"),
                      ("Happy", "Birthday"),
                      ("Merry", "XMas"),
                      ("Bye", "For Now"),
                      ("Later", "Aligator"))
    println("My map is: " + HAI_MAP)

But the decompiler gave me something that has two periods in a row and thus won't compile (I don't think this is valid Java):

scala.collection.immutable.Map HAI_MAP =
                        (Object[])new Tuple2[] {
                                new Tuple2("Hello", "World"),
                                new Tuple2("Happy", "Birthday"),
                                new Tuple2("Merry", "XMas"),
                                new Tuple2("Bye", "For Now"),
                                new Tuple2("Later", "Aligator") }));

I'm really baffled by the two periods in this:


I asked about it on #java on Freenode and they said the .. looked like a decompiler bug. It doesn't seem to want to compile, so I think they are probably right. I'm running into it when I try to browse interfaces in IntelliJ and am just generally lost.

Based on my experimentation, the following is valid:

Tuple2[] x = new Tuple2[] { new Tuple2<String,String>("Hello", "World"),
                            new Tuple2<String,String>("Happy", "Birthday"),
                            new Tuple2<String,String>("Merry", "XMas"),
                            new Tuple2<String,String>("Bye", "For Now"),
                            new Tuple2<String,String>("Later", "Aligator") };

scala.collection.mutable.WrappedArray<Tuple2> y = scala.Predef.wrapRefArray(x);

There is even a WrappedArray.toMap() method but the types of the signature are complicated and I'm running into the double-period problem there too when I try to research the interfaces from Java.

  • WHy don't you just create a "regular" map and then copy that map? I guess scala's immutable map has such a constructor?
    – fge
    Commented Jun 29, 2013 at 0:26
  • @fge Good thought. There is a MapBuilder, but you have to pass an empty collection, and then the signature of the "add-all" method is complicated: scala.collection.generic.Growable<scala.Tuple2<A,B>> $plus$plus$eq(scala.collection.TraversableOnce<scala.Tuple2<A,B>> xs). I could figure out how to make a Growable and TraversableOnce and call a method named $plus$plus$eq from Java, which IntelliJ did NOT like. Maybe I'll try that route again, but it seemed to me that there must be an easier way. Commented Jun 29, 2013 at 0:56
  • Did you look at scala.collection.JavaConversions.mapAsScalaMap ? scala-lang.org/api/current/…
    – Reuben
    Commented Jun 29, 2013 at 2:36
  • @Ruben - another good thought, but I'm specifically looking for an immutable collection and JavaConversions try to be true to the Java and use mutable collections. Commented Jul 1, 2013 at 19:45

2 Answers 2


The decompiler probably has problems in decompiling class names correctly that contain a $ symbol. The symbol you are searching for is named Predef$:

import scala.Predef;
import scala.Predef$;
import scala.Tuple2;
import scala.collection.immutable.Map;
import scala.collection.mutable.WrappedArray;

public class T {
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static void main(final String... args) {
    final Tuple2[] ts = { new Tuple2("a", "b") };
    final WrappedArray wa = Predef.wrapRefArray(ts);
    final Map<String, String> map = Predef$.MODULE$.Map().apply(wa);

Thus, I emphasize not to use a decompiler but the internal representation of the AST in scalac:

$ scala -print -e 'Map(("a", "b"))'
    Array[Tuple2]{new Tuple2("a", "b")}.$asInstanceOf[Array[Object]]()));

If you are interested in more information about how to work with the output of scalac then take a look at this question and its answers.


How about this?

java.util.Map<String, String> javaMap = new java.util.HashMap<String, String>();
javaMap.put("Hello", "World");
javaMap.put("Happy", "Birthday");
javaMap.put("Merry", "XMas");
javaMap.put("Bye", "For Now");
javaMap.put("Later", "Aligator");

scala.collection.Map<String, String> scalaMap = scala.collection.JavaConversions$.MODULE$.asMap(javaMap);
  • Maybe I'm not reading this correctly, but I think the resultant map is mutable in your example, no? I'm specifically looking for an immutable map. Commented Jul 1, 2013 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.