Per Mildner
Per Mildner

Reputation: 10487

How to call Scala's HashMap.toArray() from Java?

I use scala.collection.immutable.HashMap<A,B> from some Java code and would like to use the Scala-native method toArray() to convert the contents (or values) of the map to an array.

I currently use JavaConversions.asMap() etc, and then use the traditional, but ugly, Java toArray(T[]) methods but I would prefer to call the Scala built in method directly instead.

This must be done from Java. Rewriting the code in Scala is not an option.

I am using Scala 2.9.1.

Upvotes: 4

Views: 412

Answers (4)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297205

This should suffice:

map.toArray(scala.reflect.ClassManifest$.MODULE$.Object);

Upvotes: 1

oxbow_lakes
oxbow_lakes

Reputation: 134270

You need to supply a ClassManifest for the array type, T. This is available from the companion object (see note) for ClassManifest. So:

itr.toArray(ClassManifest$.MODULE$.fromClass(T.class));

In this example, T is a real type (not a type parameter). So for example, if itr were a Seq[String], you would use this;

itr.toArray(ClassManifest$.MODULE$.fromClass(String.class));

Because scala's Map is actually a bunch of tuples, you would use this:

map.toArray(ClassManifest$.MODULE$.fromClass(Tuple2.class));

Of course, this gives you a Tuple2[], rather than a Tuple2<K,V>[] for the key and values types K and V respectively. As you are in Java-land, you can cast the raw type


Note: accessing the companion object from Java.

The companion object of a type M is available by accessing the static field M$.MODULE$

Upvotes: 2

drexin
drexin

Reputation: 24423

calling scala specific methods from java can sometimes be very ugly like in this case. I don't know if there is a better solution to this, but this should work:

import scala.collection.immutable.HashMap;

import scala.Tuple2;
import scala.reflect.ClassManifest$;
import scala.reflect.ClassManifest;

public class Foo {
  public static void main(String[] args) {
    HashMap<String,String> map = new HashMap();
    Object ar = map.<Tuple2<String,String>>toArray((ClassManifest<Tuple2<String,String>>)ClassManifest$.MODULE$.fromClass(new Tuple2<String,String>("","").getClass()));
    System.out.println(ar.toString());
  }
}

I don't know of a way in Java to get Class<Tuple2<String,String>> without instantiating it first. In scala I would use classOf[...] is there an equivalent in java?

Upvotes: 0

soc
soc

Reputation: 28433

Judging from the API docs, it seems like you need to supply an argument of type Manifest (or of ArrayTag, depending on the version) to toArray.

Upvotes: 0

Related Questions