我可以在Java中使用scala List,例如:
import scala.collection.immutable.List;
class HelloScalaList {
public static void main (String[] args) {
List xs = List(1, 2, 3);
System.out.println(xs);
}
}
似乎没有编译。找不到List $ .apply方法。
当我将其更改为
时List xs = Dir.ls()
其中Dir是我的scala类,而ls()返回一个scala List,编译器抱怨
“内部编译器错误:java.lang.ClassCastException:org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding 无法转换为org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:927)“
我不知道这意味着什么。
我想在scala中编写一些库,但也希望在Java中使用它。
在我的scala类中有返回scala List的方法,对于使用它们的java代码,我有两个选择:
直接在java中使用scala List
编写一个包装器类,为这些方法返回java.util.List。
我更喜欢选项1,因为否则我将不得不为几乎所有的scala类编写一个包装类。
但我无法让scala List在Java中运行。
答案 0 :(得分:18)
从 Scala 2.10 开始,我没有成功完成上述技巧。
但您可以使用以下代码:
public static <T> scala.collection.immutable.List<T> scalaList(List<T> javaList) {
return scala.collection.JavaConversions.asScalaIterable(javaList).toList();
}
答案 1 :(得分:13)
一个小的java端辅助方法可以解决这个问题:
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;
}
}
<强> [更新] 强>
由于这个问题,我开始了一个名为“Scava”的小项目,以支持从Java到Scala的调用:http://code.google.com/p/scava-org/
答案 2 :(得分:6)
此语法的问题:
List xs = List(1, 2, 3);
是Scala,而不是Java。当你在Scala中实例化一个像这样的对象时,语法糖会调用类的伴随对象的apply()方法。您必须在Java中手动执行此操作。
你实际上并没有创建一个scala.collection.immutable.List(它是抽象的):
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
从Java调用Scala并不像从Scala调用Java那么有趣。我认为您可以更轻松地将Scala列表转换为Java Collection。在Java中使用任何Scala List更高阶函数都很困难,如果没有这些函数,你几乎就有了Java Collection。