Преобразование коллекции 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")