Scala如何将List[Int]转换为java.util.List[java.lang.Integer]?

36
有没有一种方法可以在Scala中将List[Int]转换为java.util.List[java.lang.Integer]?
我正在与Java(Thrift)交互。
JavaConversions支持List --> java.util.List的转换,同时也存在着Int --> java.lang.Integer的隐式转换,但是据我所知,我仍需要手动进行额外的转换。
val y = List(1)     
val z: java.util.List[Integer] = asList(y)  map { (x: Int) => x : java.lang.Integer }
6个回答

27

显然你需要进行两种类型转换,但是你可以将它们合并为单个隐式转换:

implicit def toIntegerList( lst: List[Int] ) =
  seqAsJavaList( lst.map( i => i:java.lang.Integer ) )

例子:

scala> def sizeOf( lst: java.util.List[java.lang.Integer] ) = lst.size

scala> sizeOf( List(1,2,3) )
res5: Int = 3

25

因为Int的底层表示是Integer,所以您可以直接将其转换为java.util.List[java.lang.Integer]。这样可以节省O(n)操作和一些隐式的东西。

import collection.JavaConversions._

class A {
  def l() = asList(List(1,2)).asInstanceOf[java.util.List[java.lang.Integer]]
}

那么您可以像这样从Java中使用:

A a = new A();
java.util.List<Integer> l = a.l();

请注意,在2.9.0版本中,我收到了关于asList的弃用警告(应改用seqAsJavaList


1
这似乎是最正确的答案。截至2014年,使用Scala 2.11.1仍然与scala.collection.convert.decorateAsJava相关。 - nadavwr

4

你尝试过以下方法吗:

val javalist = collection.JavaConversions.asJavaList (y)

我不确定你是需要将Int转换为Integer还是int。你可以试试看吗?

更新: 时代在变化。今天你会收到关于该代码的弃用警告。请使用以下替代方法:

import scala.collection.JavaConverters._
val y = List (1)
> y: List[Int] = List(1)

val javalist = (y).asJava
> javalist: java.util.List[Int] = [1]

看起来它实际上并没有转换底层类型,至少Idea会给我类型错误。 - Antony Stubbs
今天我只收到了一个警告,但它仍然可以工作——在回答两年后:warning: there were 1 deprecation warnings; re-run with -deprecation for details javalist: java.util.List[Int] = [1]。现在你应该使用JavaConverters。我更新了我的回答。 - user unknown

2

这个最外层没有隐式,但我喜欢这种通用方法,并已将其实现到了几种集合类型(List、Map)。

import java.util.{List => JList}
import scala.collection.JavaConverters._

  def scalaList2JavaList[A, B](scalaList: List[A])
                              (implicit a2bConversion: A => B): JList[B] =
    (scalaList map a2bConversion).asJava

由于从Int到Integer的隐式转换是标准库的一部分,因此在这种情况下的用法只需像这样:

  scalaList2JavaList[Int, Integer](someScalaList)

在另一个方向上!

(既然它们已经作为我最初的实现可用...)

import java.util.{List => JList}
import scala.collection.JavaConversions._

  def javaList2ScalaList[A, B](javaList: JList[A])
                              (implicit a2bConversion: A => B): List[B] =
    javaList.toList map a2bConversion

使用方法:

  javaList2ScalaList[Integer, Int](someJavaList)

只要包含的类型可以进行隐式转换,这样就可以重复使用所有列表。

(如果您好奇,这是我对map的实现...)

  def javaMap2ScalaMap[A, B, C, D](javaMap: util.Map[A, B])(implicit a2cConversion: A => C, b2dConversion: B => D): Map[C, D] =
    javaMap.toMap map { case (a, b) => (a2cConversion(a), b2dConversion(b)) }

1

Scala 2.13 开始,标准库包括 scala.jdk.CollectionConverters,它提供了 Scala 到 Java 的隐式集合转换。

我们可以与 java.lang.Integer::valueOf 结合使用,将 Scala 的 Int 转换为 Java 的 Integer

import scala.jdk.CollectionConverters._

List(1, 2, 3).map(Integer.valueOf).asJava
// java.util.List[Integer] = [1, 2, 3]

0
我试图将一个Map[String, Double]传递给一个Java方法。但问题在于JavaConversionsMap转换为Java Map,但保留scala Double,而不是将其转换为java.lang.Double。经过几个小时的搜索,我找到了[Alvaro Carrasco的答案](https://dev59.com/4pzha4cB1Zd3GeqPH588#40683561),只需简单地执行以下操作即可:
val scalaMap = // Some Map[String, Double]
val javaMap = scalaMap.mapValues(Double.box)

接下来,javaMap 是一个 Map[String, java.lang.Double]。然后你可以将其传递给期望一个 Map<String, Double> 的 Java 函数,并且由于隐式转换,Scala Map 将被转换为 java.util.Map

在你的情况下,只是使用 Int.box

val y = List(1)
val javay = y.map(Int.box)

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