将Scala缓冲区转换为Java ArrayList

8
在我的Scala函数中,我正在遍历一个Java ArrayCollection,提取特定元素并形成一个新集合。最后,它必须再次是Java-ArrayList,因为我正在与一个Java框架交互。 我的代码:
// to make scala-style iterating over arraylist possible
import scala.collection.JavaConversions._

// ArrayList contains elements of this type:
class Subscription(val subscriber:User, val sender:User)

// I'm getting this list from Java:
val jArrayList = new ArrayList[Subscription]
// Buffer:scala.collection.mutable.Buffer[User]
val buffer = for (val subscription <- jArrayList ) yield subscription.sender

我该如何将缓冲区转换为ArrayList[User]?或者我在这里不应该使用yield吗?

这是一个非常老的线程,但对于任何想要做相同事情的人来说 - 这里接受的答案现在已经过时了。请改用 scala.jdk.CollectionConverters - Manish Patel
3个回答

8

您应该能够通过指定您想要的buffer类型来将其转换回去(当您尝试获取的类型和您拥有的类型不兼容时,JavaConversions会自动介入):

val buffer: java.util.List[User] =
  for (val subscription <- jArrayList ) yield subscription.sender

如果你想让自己所做的事情更加清晰明了,你也可以显式地从JavaConversions中调用转换:

val buffer = asList( for ( ... ) ) // buffer should have type "java.util.List[User]"

这两种方法都不会直接产生一个ArrayList,而是创建一个通用的List,但是直接指定集合类型通常是不好的实践。如果你必须要有一个ArrayList,请将你的List传递给ArrayList的构造函数,该构造函数需要一个Collection参数:

new ArrayList( buffer )

2

您可以将缓冲区传递给ArrayList构造函数以创建一个新的Java ArrayList:

var newArray = new ArrayList[Int] (buffer)

1
这个很可能可行,因为它会隐式转换为java.util.List。虽然有时候你真的只需要一个List而不是ArrayList。 - Calum

1

当使用for comprehensions时,底层代码使用mapflatMapforeachfilterwithFilter--请参见相关问题。在这个特定的例子中,该代码等同于jArrayList.map(_.sender),而map会生成新的集合(我忽略了隐式转换,以保持简单)。

这里可能不直观的是,ArrayList没有实现map。隐式转换会给你一个Buffer,而Buffer上的map返回一个Buffer

诚然,在JavaConversions上的Buffer保留了底层集合ArrayList作为后备存储。另一方面,新创建的Buffer将不基于它,而是基于Scala自己的集合之一。

不过,你总是可以这样做:

val buffer = (for (val subscription <- jArrayList ) yield subscription.sender).asList

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