Могу ли я использовать Scala List непосредственно в Java? - PullRequest
14 голосов
/ 24 декабря 2010

Могу ли я использовать Scala List в Java, например:

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, компилятор жалуется на

"Внутренняя ошибка компилятора: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding не может быть приведен к org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding в org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable (BinaryTypeBinding.java:927) "

что я понятия не имею, что это значит.


Я хочу написать библиотеку в Scala, но также хотел бы, чтобы она использовалась в Java.

В моем классе scala есть методы, которые возвращают Scala List, для использования Java-кода у меня есть две опции:

  1. использовать scala List в java напрямую

  2. написать класс-оболочку, который возвращает java.util.List для этих методов.

Я бы предпочел вариант 1, потому что в противном случае мне придется написать класс-обертку почти для ВСЕХ моих классов Scala.

Но я не могу запустить Scala List на Java.

Ответы [ 3 ]

18 голосов
/ 16 июля 2013

Начиная с Scala 2.10 , я не справился с вышеперечисленными уловками.

Но вы можете использовать следующий код:

  public static <T> scala.collection.immutable.List<T> scalaList(List<T> javaList) {
    return scala.collection.JavaConversions.asScalaIterable(javaList).toList();
  }
13 голосов
/ 24 декабря 2010

Небольшой вспомогательный метод на стороне 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;
    }
}

[Update]

В результате этого вопроса я запустил небольшой проект под названием «Scava» для поддержки вызовов из Java в Scala: http://code.google.com/p/scava-org/

6 голосов
/ 24 декабря 2010

Проблема с этим синтаксисом:

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

Вызов Scala из Java не так увлекателен, как вызов Java из Scala. Я думаю, вам будет проще конвертировать Scala List в коллекцию Java. Использование любой из функций высшего порядка в Scala List было бы сложно в Java, и без них у вас в любом случае есть Java Collection.

...