Как преобразовать scala.List в java.util.List?

112

Как преобразовать Scala scala.Listв Java java.util.List?

Алексей Бараноски
источник
3
чувак ... изменить общепринятый ответ ... (пожалуйста)
sfletche

Ответы:

69

Scala List и Java List - два разных зверя, потому что первый неизменяем, а второй - изменчив. Итак, чтобы перейти от одного к другому, вам сначала нужно преобразовать список Scala в изменяемую коллекцию.

В Scala 2.7:

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

Начиная с 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): _*)

Однако asListв этом примере нет необходимости, если ожидаемым типом является Java List, поскольку преобразование неявное, как показано в последней строке.

Дэниел С. Собрал
источник
Val x: java.util.List [Int] по-прежнему неизменен. Просто попробуйте на Java x.add (что-то) - выдаст ошибку
Vitamon
1
@Vitamon Для меня это не вызывает никаких ошибок - я просто протестировал это, чтобы подтвердить.
Дэниел С. Собрал
4
Устарело в пользу scala.collection.JavaConvertersс 2.12 по
Йерун
для 2.12.1 при немедленном переборе списка Java с помощью цикла for Scala мне больше повезло с asScalaBuffer () в пакете JavaConverters
Сара Мессер
165

Не уверен, почему об этом не упоминалось раньше, но я думаю, что наиболее интуитивно понятный способ - вызвать asJavaметод декоратора JavaConverters непосредственно в списке 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
Это также требует, чтобы вы были явными, а не зависели от какой-то неявной магии, которая может быть нежелательной когда-то.
Камил Лелонек
Это вызывает проблемы, если сериализовать список для последующего использования в Java-коде ... это приводит к ClassNotFoundException: scala.collection.convert.Wrappers. В этом случае работает Arrays.asList (foo: _ *).
Mohan
Я захожу на эту страницу каждый раз, когда мне нужно использовать Java в Scala. К сожалению, нет никакой возможности предложить мне правильное предложение по импорту для ".asJava" ((
mulya
24

Подводя итог предыдущих ответов

Предположим, у нас есть следующее List:

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]

Если вы не хотите преобразований совместного управления и позволяете компилятору выполнять неявную работу за вас:

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]

Вам решать, как вы хотите управлять своим кодом.

Камиль Лелонек
источник
8

Начиная Scala 2.13с пакета, пакет scala.jdk.CollectionConvertersпредоставляет asJavaчерез сутенер Seqи заменяет пакеты 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

Довольно старые вопросы, хотя я отвечу, учитывая, что большинство предложений устарели.

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
прайагупд
5

Обновить

со scala 2.9.2:

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

результат

[1, 2, 3]
Гийом Массе
источник
1

Для одиночных вызовов простейшим решением может быть выполнение вручную:

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

Производительность не измерял.

Стефан В.
источник
0

Выполнение предложенного выше действия дает неизменный список даже на стороне Java. Единственное рабочее решение, которое я нашел, это следующее:

def toJList[T](l:List[T]):util.List[T] = {
  val a = new util.ArrayList[T]
  l.map(a.add(_))
  a
 }
Витамон
источник
0

Начиная с Scala 2.12.0 JavaConversions устарела.

Итак, самым простым решением для меня было:

java.util.Arrays.asList("a","b","c")
элариб
источник
1
В этом ответе не объясняется, как использовать это для преобразования списка scala в список java. Arrays.asList также может быть проблематичным, поскольку он возвращает Arrays.ArrayList, который не является списком изменяемого размера, что может вызвать некоторые неожиданные ошибки, если вы думаете, что у вас есть util.ArrayList.
puhlen 01
1
Устарение верно, есть import scala.collection.JavaConverters._на 2.12.4
прайагупд 02