【问题标题】:Converting a Java collection into a Scala collection将 Java 集合转换为 Scala 集合
【发布时间】:2010-10-15 01:17:24
【问题描述】:

与 Stack Overflow 问题相关Scala equivalent of new HashSet(Collection) ,如何将 Java 集合(java.util.List 说)转换为 Scala 集合List

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

【问题讨论】:

    标签: java scala scala-collections scala-2.7


    【解决方案1】:

    供将来参考:使用 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' answer 了解更明确的方式(使用 JavaConverters),现在似乎推荐使用。

    【讨论】:

    • 现在看来 JavaConversions 有一些隐含的含义,因此不需要调用 toSet
    • @Rajish 我认为如果转换是明确的会更好(见stackoverflow.com/questions/8301947/…
    • 你是对的,最好使用 import scala.collection.JavaConverters._
    【解决方案2】:

    如果您想比robinst's answer 中演示的 JavaConversions 更明确,可以使用 JavaConverters:

    import scala.collection.JavaConverters._
    val l = new java.util.ArrayList[java.lang.String]
    val s = l.asScala.toSet
    

    【讨论】:

      【解决方案3】:

      JavaConversions (robinst's answer) 和 JavaConverters (Ben James's answer) 已在 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”,说明这是新的和首选的用法。
      • @JoostdenBoer 似乎在 Scala 2.10 中有一些已弃用的装饰器 there,尽管它们似乎已在 Scala 2.11 中再次被删除。
      【解决方案4】:

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

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

      请注意,scala.collection.immutable.Set 在默认情况下是可用的,这要感谢Predef.scala

      【讨论】:

      • 这个建议在我想保留类型信息的地方不起作用
      【解决方案5】:

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

      【讨论】:

      • 那个图书馆是有史以来最棒的东西。真的很好用。
      • 几年后重新审视这一点,Scala 的 JavaConverters 是要走的路。
      【解决方案6】:

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

      【讨论】:

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

        可以在toArray调用中添加类型信息,使Set参数化:

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

        这可能更可取,因为 collections 包正在对 Scala 2.8 进行重大修改,而 scala.collection.jcl 包是 going away

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

          • 这不是很好,因为我的 java.util.List 是作为参数化列表从 Java API 中返回的(所以我对 API 的调用会产生 java.util.List) - 我试图把它变成一个 scala 不可变的 HashSet
          【解决方案10】:

          解决这个问题的另一种简单方法:

          import collection.convert.wrapAll._
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-08
            • 1970-01-01
            • 2012-07-25
            • 2017-01-10
            • 2011-01-10
            相关资源
            最近更新 更多