Come convertire un scala.List in un java.util.List?


Risposte:


69

Scala List e Java List sono due bestie diverse, perché la prima è immutabile e la seconda è mutabile. Quindi, per passare da uno all'altro, devi prima convertire la Scala List in una collezione modificabile.

Su Scala 2.7:

import scala.collection.jcl.Conversions.unconvertList
import scala.collection.jcl.ArrayList
unconvertList(new ArrayList ++ List(1,2,3))

Da Scala 2.8 in poi:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
asList(ListBuffer(List(1,2,3): _*))
val x: java.util.List[Int] = ListBuffer(List(1,2,3): _*)

Tuttavia, asListin quell'esempio non è necessario se il tipo previsto è Java List, in quanto la conversione è implicita, come dimostrato dall'ultima riga.


Il val x: java.util.List [Int] è ancora immutabile. Basta provare in Java a x.add (qualcosa) - genererà un errore
Vitamon

1
@ Vitamon Non genera alcun errore per me - l'ho solo testato per confermare.
Daniel C. Sobral

4
Deprecato a favore di scala.collection.JavaConvertersda 2.12 in poi
Jeroen Kransen il

per 2.12.1, quando iterando immediatamente sull'elenco Java con un ciclo Scala for, ho avuto più fortuna con asScalaBuffer () nel pacchetto JavaConverters
Sarah Messer

165

Non sono sicuro del motivo per cui questo non è stato menzionato prima, ma penso che il modo più intuitivo sia invocare il asJavametodo decorator di JavaConverters direttamente nell'elenco Scala:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

6
Richiede anche che tu sia esplicito piuttosto che dipendere da qualche magia implicita che potrebbe essere indesiderata qualche volta.
Kamil Lelonek

Ciò causa problemi se serializzare l'elenco per un uso successivo nel codice Java ... risulta in ClassNotFoundException: scala.collection.convert.Wrappers. Arrays.asList (foo: _ *) funziona in questo caso.
Mohan

Vengo su questa pagina ogni volta che ho bisogno di usare Java in Scala. Sfortunatamente non c'è modo di suggerirmi un suggerimento di importazione corretto per ".asJava" ((
mulya

24

Per riassumere le risposte precedenti

Supponendo di avere quanto segue List:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

Se vuoi essere esplicito e dire esattamente cosa vuoi convertire:

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

Se non vuoi co-controllare le conversioni e lasciare che il compilatore faccia il lavoro implicito per te:

scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._

scala> val javaList: java.util.List[Int] = scalaList
javaList: java.util.List[Int] = [1, 2, 3]

Sta a te decidere come controllare il tuo codice.


8

Iniziando Scala 2.13, il pacchetto scala.jdk.CollectionConvertersfornisce asJavatramite un magnaccia Seqe sostituisce i pacchetti scala.collection.JavaConverters/JavaConversions:

import scala.jdk.CollectionConverters._

// val scalaList: List[Int] = List(1, 2, 3)
scalaList.asJava
// java.util.List[Int] = [1, 2, 3]

7

Domande piuttosto vecchie, anche se risponderò, ma la maggior parte dei suggerimenti è deprecata.

import scala.collection.JavaConversions.seqAsJavaList

val myList = List("a", "b", "c")
val myListAsJavaList = seqAsJavaList[String](myList)

object JavaConversions in package collection is deprecated (since 2.12.0): use JavaConverters
Prayagupd

5

Aggiornare

con scala 2.9.2:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
val x: java.util.List[Int] = ListBuffer( List( 1, 2, 3 ): _* )

risultato

[1, 2, 3]

1

Per le singole invocazioni, farlo a mano potrebbe essere la soluzione più semplice:

val slist = List (1, 2, 3, 4)          
val jl = new java.util.ArrayList [Integer] (slist.size)
slist.foreach (jl.add (_))   

Non ho misurato le prestazioni.


0

Solo facendo come proposto sopra si produce un elenco immutabile anche dal lato Java. L'unica soluzione funzionante che ho trovato è questa:

def toJList[T](l:List[T]):util.List[T] = {
  val a = new util.ArrayList[T]
  l.map(a.add(_))
  a
 }

0

A partire da Scala 2.12.0 JavaConversions è stato deprecato.

Quindi la soluzione più semplice per me è stata:

java.util.Arrays.asList("a","b","c")

1
Questa risposta non spiega come usarla per convertire una lista scala in una lista java. Arrays.asList può anche essere problematico in quanto restituisce un Arrays.ArrayList che non è un elenco ridimensionabile che può causare alcuni errori imprevisti se pensi di avere un util.ArrayList.
puhlen

1
La deprecazione è vera, c'è import scala.collection.JavaConverters._per 2.12.4
Prayagupd
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.