If you want to know what affects the code, ask him.;)
This is possible with scalac -Xprint:typer <file> or the new Reflection API in 2.10:
scala> import reflect.runtime.universe._ import reflect.runtime.universe._ scala> reify{List(1,2,3).map(_+1)} res0: reflect.runtime.universe.Expr[List[Int]] = Expr[List[Int]](immutable.this.List.apply(1, 2, 3).map(((x$1) => x$1.$plus(1)))(immutable.this.List.canBuildFrom))
So call map with this CanBuildFrom and everything works fine. It's true? No no! The problem is that the Java compiler should foolishly output the arguments expected by map . So what to do? I believe that the only way is to create the necessary values, and they will drop them to death. Finally, add some SuppressWarnings-Annotations and the code should work fine .;)
Here is what I came up with:
import scala.Function1; import scala.collection.generic.CanBuildFrom; import scala.collection.immutable.List; import scala.collection.immutable.List$; import scala.runtime.AbstractFunction1; public class JTest { @SuppressWarnings({"unchecked", "rawtypes"}) public static void main(final String... args) { final List<Integer> xxx = (List) List$.MODULE$.apply(Predef.wrapIntArray(new int[] {1,2,3})); System.out.println(xxx); System.out.println(Test.sum(1, 2)); final Abc abc = new Abc(); System.out.println(abc.hello("simon")); final List<Integer> xs = (List) Test.xs(); final Function1<Integer, String> mapper = new AbstractFunction1<Integer, String>() { @Override public String apply(final Integer i) { return String.valueOf(i); } }; final CanBuildFrom<List<Integer>, String, List<String>> cbf = (CanBuildFrom) List.<Integer>canBuildFrom(); final List<String> ys = xs.<String, List<String>>map(mapper, cbf); System.out.println(ys); } }
List:
object Test { def xs = List(1,2,3) }
I find it best not to use Scala code in Java. It looks ugly. At the very least, wrap it in some helper classes so that anyone who sees this code does not think about an acid attack on the retina.
By the way, sometimes you have to look at Bytecode to understand how scalac creates values. If you want to create Scala List is Java, you need to decompile the code using javap -c -s -l -verbose -private <classfile> :
0: aload_0 1: invokespecial #20; //Method java/lang/Object."<init>":()V 4: aload_0 5: putstatic #22; //Field MODULE$:LX$; 8: aload_0 9: getstatic #27; //Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$; 12: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$; 15: iconst_3 16: newarray int 18: dup 19: iconst_0 20: iconst_1 21: iastore 22: dup 23: iconst_1 24: iconst_2 25: iastore 26: dup 27: iconst_2 28: iconst_3 29: iastore 30: invokevirtual #38; //Method scala/LowPriorityImplicits.wrapIntArray:([I)Lscala/collection/mutable/WrappedArray; 33: invokevirtual #42; //Method scala/collection/immutable/List$.apply:(Lscala/collection/Seq;)Lscala/collection/immutable/List; 36: new #44; //class X$$anonfun$1
Or in a more readable Java code:
@SuppressWarnings({"unchecked", "rawtypes"}) final List<Integer> xs = (List) List$.MODULE$.apply(Predef.wrapIntArray(new int[] {1,2,3}));