java.util.Iterator 到 Scala 列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7589561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.util.Iterator to Scala list?
提问by rshepherd
I have the following code:
我有以下代码:
private lazy val keys: List[String] = obj.getKeys().asScala.toList
obj.getKeysreturns a java.util.Iterator<java.lang.String>
obj.getKeys返回一个 java.util.Iterator<java.lang.String>
Calling asScala, via JavaConverers(which is imported) according to the docs..
根据文档调用asScala, via JavaConverers(导入)..
java.util.Iterator <==> scala.collection.Iterator
scala.collection.Iteratordefines
scala.collection.Iterator定义
def toList: List[A]
So based on this I believed this should work, however here is the compilation error:
所以基于此我相信这应该可行,但是这里是编译错误:
[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
I understand the type parameter or the java Iterator is a Java String, and that I am trying to create a list of Scala strings, but (perhaps naively) thought that there would be an implicit conversion.
我理解类型参数或 java Iterator 是一个 Java 字符串,并且我正在尝试创建一个 Scala 字符串列表,但是(也许是天真地)认为会有隐式转换。
采纳答案by Didier Dupont
That would work if obj.getKeys() was a java.util.Iterator<String>. I suppose it is not.
如果 obj.getKeys() 是一个java.util.Iterator<String>. 我想不是。
If obj.getKeys()is just java.util.Iteratorin raw form, not java.util.Iterator<String>, not even java.util.Iterator<?>, this is something scala tend to dislikes, but anyway, there is no way scala will type your expression as List[String]if it has no guarantee obj.getKeys()contains String.
如果obj.getKeys()只是java.util.Iterator原始形式,不是java.util.Iterator<String>,甚至不是java.util.Iterator<?>,这是scala 往往不喜欢的东西,但无论如何,scala 无法输入您的表达式,就List[String]好像它不能保证obj.getKeys()包含字符串一样。
If you know your iterator is on Strings, but the type does not say so, you may cast :
如果你知道你的迭代器在字符串上,但类型没有这么说,你可以强制转换:
obj.getKeys().asInstanceOf[java.util.Iterator[String]]
(then go on with .asScala.toList)
(然后继续.asScala.toList)
Note that, just as in java and because of type erasure, that cast will not be checked (you will get a warning). If you want to check immediately that you have Strings, you may rather do
请注意,就像在 java 中一样,并且由于类型擦除,将不会检查该转换(您将收到警告)。如果你想立即检查你是否有字符串,你可能宁愿这样做
obj.getKeys().map(_.asInstanceOf[String])
which will check the type of each element while you iterate to build the list
这将在您迭代构建列表时检查每个元素的类型
回答by Matthew Farwell
You don't need to call asScala, it is an implicit conversion:
你不需要调用 asScala,它是一个隐式转换:
import scala.collection.JavaConversions._
val javaList = new java.util.LinkedList[String]() // as an example
val scalaList = javaList.iterator.toList
If you really don't have the type parameter of the iterator, just cast it to the correct type:
如果您确实没有迭代器的类型参数,只需将其强制转换为正确的类型:
javaList.iterator.asInstanceOf[java.util.Iterator[String]].toList
EDIT: Some people prefer not to use the implicit conversions in JavaConversions, but use the asScala/asJava decorators in JavaConverters to make the conversions more explicit.
编辑:有些人不喜欢在 JavaConversions 中使用隐式转换,而是在 JavaConverters 中使用 asScala/asJava 装饰器来使转换更加明确。
回答by Daniel C. Sobral
I dislike the other answers. Hell, I dislike anything that suggests using asInstanceOfunless there's no alternative. In this case, there is. If you do this:
我不喜欢其他答案。地狱,我不喜欢任何建议使用的东西,asInstanceOf除非别无选择。在这种情况下,有。如果你这样做:
private lazy val keys : List[String] = obj.getKeys().asScala.collect {
case s: String => s
}.toList
You turn the Iterator[_]into a Iterator[String]safely and efficiently.
您可以安全有效地将其Iterator[_]变成一个Iterator[String]。
回答by Andriy
As of scala 2.12.8 one could use
从 Scala 2.12.8 开始,可以使用
import scala.collection.JavaConverters._
asScalaIterator(java.util.Iterator variable).toSeq
回答by Xavier Guihot
Note that starting Scala 2.13, package scala.jdk.CollectionConvertersreplaces deprecated packages scala.collection.JavaConverters/JavaConversionswhen it comes to implicit conversions between Java and Scala collections:
请注意,当涉及到 Java 和 Scala 集合之间的隐式转换时,开始Scala 2.13, packagescala.jdk.CollectionConverters替换不推荐使用的包scala.collection.JavaConverters/JavaConversions:
import scala.jdk.CollectionConverters._
// val javaIterator: java.util.Iterator[String] = java.util.Arrays.asList("a", "b").iterator
javaIterator.asScala
// Iterator[String] = <iterator>

