Jak przekonwertować scala.List do java.util.List?


Odpowiedzi:


69

Scala List i Java List to dwie różne bestie, ponieważ pierwsza jest niezmienna, a druga jest zmienna. Tak więc, aby przejść od jednej do drugiej, musisz najpierw przekonwertować listę Scala na zmienną kolekcję.

W Scali 2.7:

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

Począwszy od Scala 2.8:

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): _*)

Jednak asListw tym przykładzie nie jest to konieczne, jeśli oczekiwany typ to Java List, ponieważ konwersja jest niejawna, jak pokazano w ostatnim wierszu.


Wartość val x: java.util.List [Int] jest nadal niezmienna. Po prostu spróbuj w Javie na x.add (coś) - wyrzuci to błąd
Vitamon

1
@Vitamon Nie generuje dla mnie żadnego błędu - właśnie przetestowałem to, aby potwierdzić.
Daniel C. Sobral

4
Wycofane na korzyść scala.collection.JavaConvertersod 2.12 dnia
Jeroen Kransen

dla 2.12.1, gdy natychmiast iterowałem listę Java za pomocą pętli Scala for, miałem więcej szczęścia z asScalaBuffer () w pakiecie JavaConverters
Sarah Messer

165

Nie jestem pewien, dlaczego nie zostało to wcześniej wspomniane, ale myślę, że najbardziej intuicyjnym sposobem jest wywołanie asJavametody dekoratora JavaConverters bezpośrednio z listy 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
Wymaga również, abyś był wyraźny, a nie polegał na jakiejś ukrytej magii, która może być przez jakiś czas niepożądana.
Kamil Lelonek

Powoduje to problemy, jeśli serializowanie listy do późniejszego użycia w kodzie Java ... skutkuje ClassNotFoundException: scala.collection.convert.Wrappers. Arrays.asList (foo: _ *) działa w tym przypadku.
Mohan

Wchodzę na tę stronę za każdym razem, gdy potrzebuję języka Java w Scali. Niestety nie ma sposobu, aby zasugerować mi poprawną sugestię importu dla ".asJava" ((
mulya

24

Podsumowując poprzednie odpowiedzi

Zakładając, że mamy List:

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

Jeśli chcesz wyrazić się jasno i powiedzieć dokładnie, co chcesz przekonwertować:

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

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

Jeśli nie chcesz współkontrolować konwersji i pozwolić kompilatorowi wykonać niejawną pracę za Ciebie:

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]

To od Ciebie zależy, jak chcesz kontrolować swój kod.


8

Zaczynając Scala 2.13, pakiet scala.jdk.CollectionConvertersudostępnia asJavaza pośrednictwem pimp Seqi zastępuje pakiety 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

Odpowiem na dość stare pytania, ale większość sugestii jest przestarzała.

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

Aktualizacja

ze skalą 2.9.2:

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

wynik

[1, 2, 3]

1

W przypadku pojedynczych wywołań wykonanie tego ręcznie może być najprostszym rozwiązaniem:

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

Nie mierzyłem wydajności.


0

Postępowanie zgodnie z powyższą propozycją tworzy niezmienną listę nawet po stronie Javy. Jedyne działające rozwiązanie, które znalazłem, to:

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

0

Od Scala 2.12.0 JavaConversions jest przestarzała.

Więc najprostszym rozwiązaniem dla mnie było:

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

1
Ta odpowiedź nie wyjaśnia, jak użyć tego do konwersji listy scala na listę java. Arrays.asList może również powodować problemy, ponieważ zwraca Arrays.ArrayList, która nie jest listą o zmiennym rozmiarze, co może powodować nieoczekiwane błędy, jeśli uważasz, że masz plik util.ArrayList.
puhlen

1
Wycofanie jest prawdziwe, istnieje import scala.collection.JavaConverters._2.12.4
prayagupd
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.