【问题标题】:Implicit conversion between Scala.Long and Java.lang.Long in collections集合中 Scala.Long 和 Java.lang.Long 之间的隐式转换
【发布时间】:2014-08-28 12:35:35
【问题描述】:

我正在使用 JavaConverters 从 Java SortedSet 转换为 Vector。

    val lines = function.getInstructions.asScala.toVector

我的 getInstructions 函数返回 java.lang.Long 的 ArrayList,但使用代码需要 Scala.Long。有没有办法在不改变我所有的消费代码以使用 Java.lang.Long 的情况下做到这一点?

此外,有没有办法隐式转换为值类以允许随机访问 ArrayList 而无需像上面那样分配额外的对象?非常感谢您提供的任何见解。

【问题讨论】:

  • 您能否展示一个由于您描述的问题以及您遇到的错误而无法运行的代码示例?

标签: java scala implicit-conversion value-class


【解决方案1】:

Scala 具有自动装箱功能,所以很多时候 scala.Longjava.lang.Long。当值存储在像Vector 这样的集合中时,几乎总是会出现这种情况。目前可以安全地做一个.asInstanceOf[Vector[scala.Long]]来转换Vector的类型,但是这个could change in the future

更安全的方法是显式转换值。 Scala 在scala.Longjava.lang.Long 之间有隐式转换,但它们不会转换这些类型的集合。但是,您可以将它们与map 结合起来进行转换,例如.map(Long2long)java.lang.Long 的集合转换为scala.Long 的集合。

至于您的第二个问题,如果您导入scala.collection.JavaConversions._ 而不是JavaConverters,您将获得一组隐式转换。但是,推荐的方法是使用JavaConverters。在您的情况下,它也会更有效,因为包装器只需创建一次。

如果你真的喜欢快速和危险的游戏,你可以编写自己的隐式转换:

implicit def convArrayList(al: ArrayList[java.lang.Long]): Vector[Long] =
  al.asScala.map(Long2long)(collection.breakOut)

【讨论】:

  • @DanGetz 你说得对,实际上是Predef 中的隐式转换发挥了作用。我已经更改了答案以反映这一点。
  • 当枚举元素时,该映射是否隐式创建了一个新的数据结构,还是以某种方式透明地访问抽象的 ArrayList?
  • 它创建了一个新的数据结构。您可以编写一个来提供透明访问,但这会更复杂。
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多