我可以直接在Java中使用scala List吗?

时间:2010-12-24 07:23:55

标签: java scala-collections scala-java-interop

我可以在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代码,我有两个选择:

  1. 直接在java中使用scala List

  2. 编写一个包装器类,为这些方法返回java.util.List。

  3. 我更喜欢选项1,因为否则我将不得不为几乎所有的scala类编写一个包装类。

    但我无法让scala List在Java中运行。

3 个答案:

答案 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。