4

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.

4 Answers 4

2

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$

Sign up to request clarification or add additional context in comments.

5 Comments

I assume that ClassManifest$.MODULE$ is the ClassManifest object defined in ClassManifest.scala. I worry about the its documentaton, which says "It is intended for use by the compiler and should not be used in client code."
As for "the companion object", it is presumably not available for plain Java types (unless Scala is more powerful than I think). In that case, is ClassManifest$.MODULE$.fromClass(SomeType.class) OK to use also for Scala types (like Tuple2, which should already have a predefined Tuple2$.MODULE$)?
Using (SomeType[])(...some Scala collection).toArray(ClassManifest$.MODULE$.fromClass(SomeType.class)) seems to work well. My only worry is the documentation that claims that ClassManifest is off limits for client code.
Indeed; in theory, the scala team could change this. However, I doubt they would do so without eliciting community feedback. One more thing: don't forget, scala is just a JAR file at runtime. Just because a new version of scala is released doesn't force you to put it on your classpath
I thought objects were supposed to have static forwarder methods so you don't need the whole $.MODULE$ thing... don't they work in this case?
1

This should suffice:

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

Comments

0

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.

Comments

0

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?

5 Comments

.class should get you the class in the same way as classOf
Okay, found a dirty solution ;-). (Class<Tuple2<String,String>>)(Object)Tuple2.class works.
Just drop the type parameters. Type parameters are not relevant to a Class.
If you want to get a typed result it is relevant.
@drexin - but the types lie. There's no such thing as a T<U>[] and code should not behave as if there is

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.