14

Can I use scala List in Java, like :

import scala.collection.immutable.List;
class HelloScalaList {
    public static void main (String[] args) {
        List xs = List(1, 2, 3);
        System.out.println(xs);
    }
}

It does not seem to compile. can't find List$.apply method.

when I change it to

List xs = Dir.ls()

where Dir is my scala class, and ls() returns a scala List, the compiler complaints about

"Internal compiler error: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:927)"

which I have no idea what it means.


I want to write some library in scala, but would also like it to be used in Java.

In my scala class there are methods that return scala List, for java code to use them, I have two options:

  1. use scala List in java directly

  2. write a wrapper class that returns java.util.List for those methods.

I'd rather like option 1, because otherwise I'll have to write a wrapper class for nearly ALL my scala classes.

But I just can't get scala List running in Java.

3 Answers 3

18

As of Scala 2.10, I didn't succeed with the tricks above.

But you can use the following code:

  public static <T> scala.collection.immutable.List<T> scalaList(List<T> javaList) {
    return scala.collection.JavaConversions.asScalaIterable(javaList).toList();
  }
Sign up to request clarification or add additional context in comments.

Comments

14

A little java-side helper method does the trick:

import scala.collection.immutable.List;
import scala.collection.immutable.List$;
import scala.collection.immutable.$colon$colon;

public class HelloScalaList {

    public static void main (String[] args) {
        List xs = list(1,2,3);
        System.out.println(xs);
    }

    public static <T> List<T> list(T ... ts) {
        List<T> result = List$.MODULE$.empty();
        for(int i = ts.length; i > 0; i--) {
            result = new $colon$colon(ts[i - 1], result);
        }
        return result;
    }
}

[Update]

As a result of this question, I started a little project called "Scava" in order to support calls from Java to Scala: http://code.google.com/p/scava-org/

3 Comments

Thanks for your effort, but what's the advantage to converting the Scala list to a Java one, as pointed out by Janx?
@Luigi Plinge: linky killed, because it wasn't as useful as I thought, had some dangerous stuff inside, and integration got better with Scala 2.9.
tested in Scala 2.12, I can't not import $colon$colon directly, instead I need to import scala.collection.immutable.*;
6

The problem with this syntax:

List xs = List(1, 2, 3);

is that it's Scala, not Java. When you instantiate an object like that in Scala, syntactic sugar calls the apply() method of the class' companion object. You would have to do that manually in Java.

And you aren't actually creating a scala.collection.immutable.List (which is abstract):

scala> val list = List(1,2,3)                      
list: List[Int] = List(1, 2, 3)
scala> list.getClass                               
res12: java.lang.Class[_] = class scala.collection.immutable.$colon$colon

Calling Scala from Java isn't nearly as fun as calling Java from Scala. I think you'll have an easier time converting the Scala List to a Java Collection. Using any of the Scala List higher order functions would be difficult in Java and without those, you pretty much have a Java Collection anyway.

Comments

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.