Преобразование коллекции Java в коллекцию Scala

связанный с вопросом переполнения стека Scala эквивалент нового HashSet (коллекция) , как преобразовать коллекцию Java (java.util.List say) в коллекцию Scala List?

Я на самом деле пытаюсь преобразовать вызов Java API в весной SimpleJdbcTemplate, который возвращает java.util.List<T>, в неизменяемую Scala HashSet. Так например:

val l: java.util.List[String] = javaApi.query( ... )
val s: HashSet[String] = //make a set from l

это, кажется, работает. Критика приветствуется!

import scala.collection.immutable.Set
import scala.collection.jcl.Buffer 
val s: scala.collection.Set[String] =
                      Set(Buffer(javaApi.query( ... ) ) : _ *)

9 ответов


ваше последнее предложение работает, но вы также можете избежать использования jcl.Buffer:

Set(javaApi.query(...).toArray: _*)

отметим, что scala.collection.immutable.Set доступно по умолчанию спасибо Predef.scala.


для дальнейшего использования: с Scala 2.8 это можно сделать следующим образом:

import scala.collection.JavaConversions._
val list = new java.util.ArrayList[String]()
list.add("test")
val set = list.toSet

set это scala.collection.immutable.Set[String] после этого.

см. Также ответ Бена Джеймса для более явного способа (используя JavaConverters), который, кажется, рекомендуется сейчас.


Если вы хотите быть более явными, чем JavaConversions, продемонстрированные в robinst это, вы можете использовать JavaConverters:

import scala.collection.JavaConverters._
val l = new java.util.ArrayList[java.lang.String]
val s = l.asScala.toSet

JavaConversions (robinst это) и JavaConverters (ответ Бена Джеймса) были осуждены с Scala 2.10.

вместо JavaConversions использование:

import scala.collection.convert.wrapAll._

как было предложено aleksandr_hramcov.

вместо JavaConverters использование:

import scala.collection.convert.decorateAll._

для обоих также есть возможность импортировать только конверсии / конвертеры в Java или Scala соответственно, например:

import scala.collection.convert.wrapAsScala._

обновление: Утверждение выше этого JavaConversions и JavaConverters устарели кажется неправильным. В Scala 2.10 были некоторые устаревшие свойства, что привело к предупреждениям об устаревании при их импорте. Таким образом, альтернативный импорт здесь, похоже, только псевдонимы. Хотя я все еще предпочитаю их, поскольку ИМХО имена более уместны.


вы также можете изучить эту отличную библиотеку:scalaj-коллекция это имеет двустороннее преобразование между коллекциями Java и Scala. В вашем случае, чтобы преобразовать java.утиль.Список в список Scala вы можете сделать это:

val list = new java.util.ArrayList[java.lang.String]
list.add("A")
list.add("B")
list.asScala

val array = java.util.Arrays.asList("one","two","three").toArray

val list = array.toList.map(_.asInstanceOf[String])

вы можете добавить информацию о типе в вызов toArray, чтобы сделать набор параметризованным:

 val s = Set(javaApi.query(....).toArray(new Array[String](0)) : _*)

это может быть предпочтительнее, так как пакет коллекций проходит серьезную переработку для Scala 2.8 и scala.коллекция.пакет jcl является уходит


еще один простой способ решить эту проблему:

import collection.convert.wrapAll._

вы можете преобразовать коллекцию Java в массив, а затем создать список Scala из этого:

val array = java.util.Arrays.asList("one","two","three").toArray
val list = List.fromArray(array)