java.util.Iterator到Scala列表?

rsh*_*erd 18 scala scala-java-interop scala-collections

请耐心等待,我对斯卡拉来说还是很吵.我有以下代码:

private lazy val keys: List[String] = obj.getKeys().asScala.toList
Run Code Online (Sandbox Code Playgroud)

obj.getKeys返回一个java.util.Iterator

根据文档通过JavaConverers(导入)调用asScala ..

java.util.Iterator <==> scala.collection.Iterator 
Run Code Online (Sandbox Code Playgroud)

scala.collection.Iterator定义

def toList: List[A] 
Run Code Online (Sandbox Code Playgroud)

基于此,我认为这应该可行,但这里是编译错误.

[scalac]  <file>.scala:11: error: type mismatch;
[scalac]  found   : List[?0] where type ?0
[scalac]  required: List[String]
[scalac]  private lazy val keys : List[String] = obj.getKeys().asScala.toList
[scalac]  one error found
Run Code Online (Sandbox Code Playgroud)

我理解类型参数或java Iterator是一个Java字符串,我试图创建一个Scala字符串列表,但(或许天真地)认为会有一个隐式转换.

Mat*_*ell 25

你不需要调用asScala,它是一个隐式转换:

import scala.collection.JavaConversions._

val javaList = new java.util.LinkedList[String]() // as an example

val scalaList = javaList.iterator.toList
Run Code Online (Sandbox Code Playgroud)

如果您确实没有迭代器的type参数,只需将其强制转换为正确的类型:

javaList.iterator.asInstanceOf[java.util.Iterator[String]].toList
Run Code Online (Sandbox Code Playgroud)

编辑:有些人不喜欢在JavaConversions中使用隐式转换,而是使用JavaConverters中的asScala/asJava装饰器来使转换更加明确.


Did*_*ont 12

如果obj.getKeys()是一个,那将会有效java.util.Iterator<String>.我想不是.

如果obj.getKeys()只是java.util.Iterator原始形式,不是java.util.Iterator<String>,甚至不是java.util.Iterator<?>,这是scala倾向于不喜欢的东西,但无论如何,scala不会输入你的表达式,List[String]好像它没有保证obj.getKeys()包含String.

如果你知道你的迭代器是在字符串上,但是类型没有这么说,你可以强制转换:

obj.getKeys().asInstanceOf[java.util.Iterator[String]]
Run Code Online (Sandbox Code Playgroud)

(然后继续.asScala.toList)

请注意,就像在java中一样,因为类型擦除,不会检查该转换(您将收到警告).如果你想立即检查你有字符串,你可能宁愿这样做

obj.getKeys().map(_.asInstanceOf[String])
Run Code Online (Sandbox Code Playgroud)

这将在您迭代构建列表时检查每个元素的类型