20

私は次のコードを持っています:

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パラメーターまたはjavaIteratorがJava文字列であり、Scala文字列のリストを作成しようとしていることは理解していますが、(おそらく単純に)暗黙の変換があると思いました。

4

5 に答える 5

26

You don't need to call asScala, it is an implicit conversion:

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.

于 2011-09-28T21:19:33.767 に答える
11

obj.getKeys() がjava.util.Iterator<String>. そうではないと思います。

obj.getKeys()がそのままのjava.util.Iterator形式で、java.util.Iterator<String>ではなく でさえない場合、java.util.Iterator<?>これは scala が嫌う傾向にありますが、とにかく、Scala が文字列を含む List[String]保証がないかのように式を型付けする方法はありません。obj.getKeys()

イテレータが文字列上にあることがわかっているが、型がそうではない場合は、次のようにキャストできます。

obj.getKeys().asInstanceOf[java.util.Iterator[String]]

(次に進みます.asScala.toList

Java と同様に、型の消去のために、そのキャストはチェックされないことに注意してください (警告が表示されます)。文字列があることをすぐに確認したい場合は、むしろそうすることができます

obj.getKeys().map(_.asInstanceOf[String])

リストを作成するために繰り返しながら、各要素のタイプをチェックします

于 2011-09-28T21:39:42.913 に答える
3

私は他の答えが嫌いです。asInstanceOf地獄、代替手段がない限り、使用を提案するものは嫌いです。この場合、あります。これを行う場合:

private lazy val keys : List[String] = obj.getKeys().asScala.collect { 
    case s: String => s 
}.toList

Iterator[_]Iterator[String]安全かつ効率的に に変えます。

于 2011-10-01T23:02:36.597 に答える