Вопрос

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

На самом деле я пытаюсь преобразовать вызов API Java в Весна 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( ... ) ) : _ *)
Это было полезно?

Решение

Ваше последнее предложение работает, но вы также можете избежать использования 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, показанные в ответ Робинста, вы можете использовать JavaConverters:

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

JavaКонверсии (ответ Робинста) и JavaКонвертеры (Ответ Бена Джеймса) устарели с Скала 2.10.

Вместо JavaКонверсии использовать:

import scala.collection.convert.wrapAll._

как было предложено Александр Храмков.

Вместо JavaКонвертеры использовать:

import scala.collection.convert.decorateAll._

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

import scala.collection.convert.wrapAsScala._

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

Вы также можете изучить эту замечательную библиотеку: scalaj-коллекция который имеет двустороннее преобразование между коллекциями Java и Scala.В вашем случае, чтобы преобразовать java.util.List в список 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, чтобы параметризовать Set:

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

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

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

import collection.convert.wrapAll._

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

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

Начало 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")
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top