将Java集合转换为Scala集合


87

与Stack Overflow问题Scala与新的HashSet(Collection)等效,我如何将Java集合(java.util.List例如)转换为Scala集合List

我实际上是在尝试将Java API调用转换为Spring的 SimpleJdbcTemplate(返回a 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( ... ) ) : _ *)

Answers:


17

您的最后一条建议有效,但您也可以避免使用jcl.Buffer

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

请注意,scala.collection.immutable.Set默认情况下,由于可以使它可用Predef.scala


9
这个建议在我想保留类型信息的地方
不起作用

126

供将来参考:使用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]之后的。

另请参阅Ben James的答案以更明确的方式(使用JavaConverters),现在似乎建议这样做。


看起来现在JavaConversions有一些隐式toSet调用,因此不需要调用。
拉吉什2012年

@Rajish我认为这是更好,如果转换是明确的(见stackoverflow.com/questions/8301947/...
krookedking

没错,最好使用import scala.collection.JavaConverters._
Abhishek Sengupta


25

JavaConversions罗宾斯特的答案)和JavaConvertersBen 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._

更新: 以上关于JavaConversionsJavaConverters已过时的声明似乎是错误的。Scala 2.10中有一些已弃用的属性,在导入它们时会导致弃用警告。因此,这里的替代导入似乎只是别名。尽管我仍然喜欢它们,但作为恕我直言,这些名称更合适。


为什么说JavaConversions和JavaConverters已过时?在当前文档2.11.8中,这两个标记都未标记为已弃用,并且也没有引用“ decorateAll”或“ wrapAll”来说明这是新的且首选的用法。
Joost den Boer

@JoostdenBoer似乎有一些过时的装修在斯卡拉2.10,尽管他们似乎已经使用Scala 2.11再次删除。
stempler's

14

您可能还想探索这个出色的库: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

1
那个图书馆是有史以来最伟大的事情。真的真的很好。
Michael Neale 2010年

6
几年后重新研究这一点,Scala的JavaConverters是必经之路。
Surya Suravarapu 2012年

4

开始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")

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

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

这是一个很好的答案,解决了我的问题。互联网上提到的大多数方法只是将java.util.List [java.lang.Long]转换为scala.collection.immutable.List [java.lang.Long]。因此,该方法对我有用,可以将其转换为scala.collection.immutable.List [scala.Long]
ajkl 2014年

2

您可以在toArray调用中添加类型信息,以对Set进行参数化:

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

这可能是更可取的选择,因为collections包将对Scala 2.8进行一次重大返工,而scala.collection.jcl包将不复存在。


1

您可以将Java集合转换为数组,然后从中创建一个Scala列表:

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

2
这不是很好,因为我的java.util.List从Java API中返回为参数化列表(所以我对API的调用产生了java.util.List <String>)-我试图将其进入标量不变的HashSet
oxbow_lakes

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.