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?