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.