Преобразование коллекции Java в коллекцию Scala
Относящиеся к переполнению стека вопрос Scala эквивалент новой HashSet (Collection), как преобразовать коллекцию Java (java.util.List
говорят) в коллекции Scala List
?
Я на самом деле пытаюсь преобразовать API вызов Java в Spring, java.util.List<T>
HashSet
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( ... ) ) : _ *)
Ответы
Ответ 1
Ваше последнее предложение работает, но вы также можете избежать использования jcl.Buffer
:
Set(javaApi.query(...).toArray: _*)
Обратите внимание, что scala.collection.immutable.Set
становится доступным по умолчанию благодаря Predef.scala
.
Ответ 2
В будущем: С 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), который, кажется, рекомендуется сейчас.
Ответ 3
Если вы хотите быть более явным, чем JavaConversions, продемонстрированные в robinst answer, вы можете использовать JavaConverters:
import scala.collection.JavaConverters._
val l = new java.util.ArrayList[java.lang.String]
val s = l.asScala.toSet
Ответ 4
JavaConversions (ответ robinst) и JavaConverters (ответ Ben James) устарели Scala 2.10.
Вместо JavaConversions используйте:
import scala.collection.convert.wrapAll._
как было предложено aleksandr_hramcov.
Вместо JavaConverters используйте:
import scala.collection.convert.decorateAll._
Для обоих есть возможность только импортировать конверсии/конвертеры в Java или Scala соответственно, например:
import scala.collection.convert.wrapAsScala._
Update:
Утверждение выше, что JavaConversions и JavaConverters были устаревшими, кажется неправильным. В Scala 2.10 были некоторые устаревшие свойства, что привело к предупреждению об утомлении при импорте. Таким образом, альтернативный импорт здесь представляет собой только псевдонимы. Хотя я по-прежнему предпочитаю их, как ИМХО, имена более уместны.
Ответ 5
Вы также можете изучить эту отличную библиотеку: scalaj-collection, которая имеет двустороннее преобразование между коллекциями Java и Scala. В вашем случае, чтобы преобразовать java.util.List в Scala List, вы можете сделать это:
val list = new java.util.ArrayList[java.lang.String]
list.add("A")
list.add("B")
list.asScala
Ответ 6
val array = java.util.Arrays.asList("one","two","three").toArray
val list = array.toList.map(_.asInstanceOf[String])
Ответ 7
Вы можете добавить информацию о типе в вызов toArray, чтобы настроить параметр Set:
val s = Set(javaApi.query(....).toArray(new Array[String](0)) : _*)
Это может быть предпочтительнее, так как пакет коллекций проходит серьезную доработку для Scala 2.8, а пакет scala.collection.jcl собирается прочь
Ответ 8
Еще один простой способ решить эту проблему:
import collection.convert.wrapAll._
Ответ 9
Вы можете преобразовать коллекцию Java в массив и затем создать список Scala:
val array = java.util.Arrays.asList("one","two","three").toArray
val list = List.fromArray(array)
Ответ 10
Начиная с Scala 2.13
, пакет scala.jdk.CollectionConverters
заменяет пакеты scala.collection.JavaConverters/JavaConversions._
:
import scala.jdk.CollectionConverters._
// val javaList: java.util.List[String] = java.util.Arrays.asList("one","two","three")
javaList.asScala
// collection.mutable.Buffer[String] = Buffer("one", "two", "three")
javaList.asScala.toSet
// collection.immutable.Set[String] = Set("one", "two", "three")