如何将scala.List转换为java.util.List?

135

如何将Scala的scala.List转换为Java的java.util.List


5
老兄,请更改已接受的答案...(请) - sfletche
9个回答

184

不确定为什么之前没有提到过,但我认为最直观的方法是直接在Scala列表上调用asJava修饰器方法,该方法位于JavaConverters中。

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

6
这也要求您明确表达,而不依赖于某些可能在某些时候不需要的隐含魔法。 - Kamil Lelonek
如果将列表序列化以供Java代码后续使用,则会出现问题...这会导致ClassNotFoundException: scala.collection.convert.Wrappers。在这种情况下,Arrays.asList(foo : _*)可以解决问题。 - Mohan
每次我在Scala中使用Java时,我都会来到这个页面。不幸的是,IDEA无法为“.asJava”提供正确的导入建议。 - mulya

70

Scala的List和Java的List是两个不同的东西,前者是不可变的,后者是可变的。因此,要从一个转换为另一个,你首先需要将Scala List转换为可变集合。

在Scala 2.7上:

import scala.collection.jcl.Conversions.unconvertList
import scala.collection.jcl.ArrayList
unconvertList(new ArrayList ++ List(1,2,3))

从Scala 2.8版本开始:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
asList(ListBuffer(List(1,2,3): _*))
val x: java.util.List[Int] = ListBuffer(List(1,2,3): _*)

然而,在该示例中,如果期望的类型是Java List,则asList不是必需的,因为转换是隐式的,就像最后一行所示。


val x: java.util.List[Int]仍然是不可变的。在Java中尝试x.add(something) - 它会抛出错误。 - Vitamon
1
@Vitamon 对我来说它没有抛出任何错误 - 我刚刚测试了一下以确认。 - Daniel C. Sobral
4
从2.12版本开始,建议使用scala.collection.JavaConverters代替此方法。 - Jeroen Kransen
对于2.12.1版本,在使用Scala for循环直接迭代Java List时,我在JavaConverters包中使用asScalaBuffer()方法取得更好的效果:https://www.scala-lang.org/api/2.12.1/scala/collection/JavaConverters$.html - Sarah Messer

26

总结之前的回答

假设我们有如下的List

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)
如果你想要更加明确地说明你想要转换的内容:
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]
如果您不想控制转换,而是让编译器为您进行隐式转换,请使用以下代码:
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._

scala> val javaList: java.util.List[Int] = scalaList
javaList: java.util.List[Int] = [1, 2, 3]

你可以自己决定如何控制你的代码。


23

Scala 2.13 开始,scala.jdk.CollectionConverters 包通过 Seq 的增强转换提供了 asJava 方法,替代了原来的包 scala.collection.JavaConverters/JavaConversions

import scala.jdk.CollectionConverters._

// val scalaList: List[Int] = List(1, 2, 3)
scalaList.asJava
// java.util.List[Int] = [1, 2, 3]

9

虽然这些问题有点老,但我会回答。不过大部分建议都已经过时了。

import scala.collection.JavaConversions.seqAsJavaList

val myList = List("a", "b", "c")
val myListAsJavaList = seqAsJavaList[String](myList)

object JavaConversions in package collection is deprecated (since 2.12.0): use JavaConverters - prayagupa

6

更新

使用scala 2.9.2版本:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
val x: java.util.List[Int] = ListBuffer( List( 1, 2, 3 ): _* )

结果

[1, 2, 3]

1

对于单次调用,手动操作可能是最简单的解决方案:

val slist = List (1, 2, 3, 4)          
val jl = new java.util.ArrayList [Integer] (slist.size)
slist.foreach (jl.add (_))   

我没有测量性能。


0

按照上面提出的方法进行操作,即使在Java端也会生成不可变列表。 我找到的唯一有效的解决方案是:

def toJList[T](l:List[T]):util.List[T] = {
  val a = new util.ArrayList[T]
  l.map(a.add(_))
  a
 }

-1

1
这个答案没有解释如何使用它将Scala列表转换为Java列表。Arrays.asList也可能存在问题,因为它返回一个Arrays.ArrayList,它不是可调整大小的List,如果您认为您有一个util.ArrayList,这可能会导致一些意外的错误。 - puhlen
3
弃用是真实存在的,对于2.12.4版本有import scala.collection.JavaConverters._ - prayagupa
scala.jdk.CollectionConverters._asJava是我认为的正确方式。 - jaecktec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接