【问题标题】:Scala convert List[Int] to a java.util.List[java.lang.Integer]Scala 将 List[Int] 转换为 java.util.List[java.lang.Integer]
【发布时间】:2011-10-22 21:50:42
【问题描述】:

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 }

【问题讨论】:

    标签: scala scala-java-interop


    【解决方案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]
    

    【讨论】:

      【解决方案2】:

      我试图将 Map[String, Double] 传递给 Java 方法。但问题是JavaConversionsMap 转换为java Map,但保留scala Double,而不是将其转换为java.lang.Double。经过几个小时的搜索,我找到了 [Alvaro Carrasco 的回答])https://stackoverflow.com/a/40683561/1612432),就这么简单:

      val scalaMap = // Some Map[String, Double]
      val javaMap = scalaMap.mapValues(Double.box)
      

      在此之后,javaMapMap[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)
      

      【讨论】:

        【解决方案3】:

        这在最外层没有隐式,但我喜欢这种通用方法,并且已经为几种类型的集合(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)
        

        只要包含类型的隐式转换在范围内,它就可以重新用于所有列表。

        (如果你好奇,这是我的地图实现......)

          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)) }
        

        【讨论】:

          【解决方案4】:

          你试过了吗:

          val javalist = collection.JavaConversions.asJavaList (y)
          

          我不确定,这里是否需要转换 Int=>Integer 或 Int=>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 给了我类型错误。
          • 我今天才收到警告,但它仍在工作 - 2 年后回答:warning: there were 1 deprecation warnings; re-run with -deprecation for details javalist: java.util.List[Int] = [1]。今天你将使用 JavaConverters。我更新了我的答案。
          【解决方案5】:

          因为 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

          【讨论】:

          • 这似乎是最正确的答案。截至 2014 年,Scala 2.11.1 仍与 scala.collection.convert.decorateAsJava 相关。
          【解决方案6】:

          显然您需要两种转换。但是,您可以将它们分组到一个隐式转换中:

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-03-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-14
            • 2013-04-16
            • 1970-01-01
            相关资源
            最近更新 更多