私は次のコードを持っています:
private lazy val keys: List[String] = obj.getKeys().asScala.toList
obj.getKeys
はJava.util.Iterator<Java.lang.String>
を返します
ドキュメントによると、asScala
(インポートされます)を介してJavaConverers
を呼び出します。
Java.util.Iterator <==> scala.collection.Iterator
scala.collection.Iterator
は定義します
def toList: List[A]
したがって、これに基づいて、これは機能するはずだと思いましたが、コンパイルエラーは次のとおりです。
[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
TypeパラメーターまたはJavaイテレーターがJava文字列であり、Scala文字列のリストを作成しようとしていることを理解していますが、(おそらく単純に)暗黙の変換があるだろうと思った。
Obj.getKeys()が_Java.util.Iterator<String>
_の場合、これは機能します。そうではないと思います。
obj.getKeys()
が生の形式で_Java.util.Iterator
_であり、_Java.util.Iterator<String>
_ではなく、_Java.util.Iterator<?>
_でさえない場合、これは何かscala嫌いになる傾向があります、しかしとにかく、obj.getKeys()
に文字列が含まれているという保証がない場合、scalaは式を_List[String]
_として入力する方法はありません。
イテレータが文字列上にあることがわかっているが、型がそう言っていない場合は、次のようにキャストできます。
_obj.getKeys().asInstanceOf[Java.util.Iterator[String]]
_
(その後、_.asScala.toList
_を続行します)
Javaの場合と同様に、型消去のため、そのキャストはチェックされません(警告が表示されます)。文字列があることをすぐに確認したい場合は、むしろ行う
_obj.getKeys().map(_.asInstanceOf[String])
_
リストの作成を繰り返す間、各要素のタイプをチェックします
AsScalaを呼び出す必要はありません。これは暗黙的な変換です。
import scala.collection.JavaConversions._
val javaList = new Java.util.LinkedList[String]() // as an example
val scalaList = javaList.iterator.toList
イテレータのtypeパラメータが本当にない場合は、正しい型にキャストしてください。
javaList.iterator.asInstanceOf[Java.util.Iterator[String]].toList
編集:JavaConversionsで暗黙的な変換を使用したくない人もいますが、JavaConvertersでasScala/asJavaデコレータを使用して、変換をより明示的にします。
私は他の答えが嫌いです。地獄、私は代替手段がない限り、asInstanceOf
の使用を提案するものは何でも嫌いです。この場合、あります。これを行う場合:
private lazy val keys : List[String] = obj.getKeys().asScala.collect {
case s: String => s
}.toList
Iterator[_]
をIterator[String]
に安全かつ効率的に変換します。
scala 2.12.8の時点で、
import scala.collection.JavaConverters._
asScalaIterator(Java.util.Iterator variable).toSeq
JavaコレクションとScalaコレクション間の暗黙的な変換に関しては、Scala 2.13
、package scala.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>