Java <-> Scala interop: przezroczysta konwersja list i map

Uczę się Scali i mam projekt Java do migracji do Scala. Chcę go zmigrować, przepisując klasy jeden po drugim i sprawdzając, czy nowa klasa nie złamała projektu.

Ten projekt Java wykorzystuje wielejava.util.List ijava.util.Map. W nowych klasach Scala chciałbym korzystać ze ScalaList iMap mieć dobrze wyglądający kod Scala.

Problem polega na tym, że nowe klasy (te z wtyczką w Scali) nie integrują się bezwiednie z istniejącym kodem Java: Java potrzebujejava.util.List, Scala potrzebuje własnegoscala.List.

Oto uproszczony przykład problemu. Są klasyGłówny, Logika, Dao. Dzwonią do siebie w linii:Główne -> Logika -> Dao.

public class Main {
    public void a() {
        List<Integer> res = new Logic().calculate(Arrays.asList(1, 2, 3, 4, 5));
    }
}

public class Logic {
    public List<Integer> calculate(List<Integer> ints) {
        List<Integer> together = new Dao().getSomeInts();
        together.addAll(ints);
        return together;
    }
}

public class Dao {
    public List<Integer> getSomeInts() {
        return Arrays.asList(1, 2, 3);
    }
}

W mojej sytuacji zajęciaGłówny iDao są klasami szkieletowymi (nie muszę ich migrować). KlasaLogika jest logiką biznesową i przyniesie wiele korzyści z fajnych funkcji Scala.

Muszę przepisać klasęLogika w Scali, zachowując integralność z klasamiGłówny iDao. Wyglądałoby na to, że najlepsze przepisanie (nie działa):

class Logic2 {
  def calculate(ints: List[Integer]) : List[Integer] = {
      val together: List[Integer] = new Dao().getSomeInts()
      together ++ ints
  }
}

Idealne zachowanie: lista wewnątrzLogika2 są rodzimymi listami Scala. Wszystkie wejścia / wyjściajava.util.Lists automatycznie zapakowane / rozpakowane. Ale to nie działa.

Zamiast tego działa (dziękiscala-javautils (GitHub)):

import org.scala_tools.javautils.Implicits._

class Logic3 {
  def calculate(ints: java.util.List[Integer]) : java.util.List[Integer] = {
      val together: List[Integer] = new Dao().getSomeInts().toScala
      (together ++ ints.toScala).toJava
  }
}

Ale wygląda brzydko.

Jak uzyskać przezroczystą magiczną konwersję list i map między Javą <-> Scala (bez konieczności zrobienia toScala / toJava)?

Jeśli nie jest to możliwe, jakie są najlepsze praktyki dotyczące migracji Java -> kodu Scala, który używajava.util.List i przyjaciele?

questionAnswers(3)

yourAnswerToTheQuestion