Sto imparando Scala e ho un progetto Java per migrare a Scala. Voglio migrarlo riscrivendo le classi una alla volta e controllando che la nuova classe non abbia infranto il progetto.Java <-> Scala interop: conversione elenco e mappa trasparente
Questo progetto Java utilizza molto java.util.List
e java.util.Map
. Nelle nuove classi di Scala mi piacerebbe usare lo List
di Scala e lo Map
per avere un codice Scala di bell'aspetto.
Il problema è che le nuove classi (quelle che sono scritte in Scala) non si integrano perfettamente con il codice Java esistente: Java ha bisogno di java.util.List
, Scala ha bisogno del proprio scala.List
.
Ecco un esempio semplificato del problema. Esistono classi Principale, Logica, Dao. Si chiamano in una riga: Principale -> Logica -> 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);
}
}
Nella mia situazione, le classi principale e Dao sono classi del framework (Non ho bisogno di migrare loro). Classe La logica è business-logic e trarrà un grande vantaggio dalle funzionalità di Scala.
Ho bisogno di riscrivere classe Logic a Scala, preservando l'integrità con le classi principale e Dao. La migliore riscrittura sarà simile (non funziona):
class Logic2 {
def calculate(ints: List[Integer]) : List[Integer] = {
val together: List[Integer] = new Dao().getSomeInts()
together ++ ints
}
}
comportamento ideale: liste all'interno Logic2 sono nativi Scala Liste. Tutto dentro/fuori java.util.Lists
ottiene un box/unboxed automaticamente. Ma questo non funziona.
Invece, questo fa di lavoro (grazie alla scala-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
}
}
Ma sembra brutto.
Come si ottiene la conversione magica trasparente di elenchi e mappe tra Java < -> Scala (senza necessità di eseguire toScala/toJava)?
Se non è possibile, quali sono le migliori pratiche per la migrazione di Java -> codice Scala che utilizza java.util.List
e gli amici?
molto ben inserito, +1 – geowa4
(+1) molto ben indicato. Vorrei che questo post fosse stato in giro quando ho lottato con esso qualche tempo fa. – Shaun
Grazie per questo scrupolo approfondito. Trovato tramite google (ovviamente!) quindi hai già salvato un sacco di dolore a qualcuno! –