2011-09-28 15 views
13

私と一緒にお立ち寄りください、私はまだかなりScalaとnoobishです。java.util.Iterator to Scalaリスト?

private lazy val keys : List[String] = obj.getKeys().asScala.toList 

obj.getKeysがドキュメントに従って(インポートする)JavaConverers介し

asScalaをコールするjava.util.Iteratorを返す..

java.util.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 

私は型パラメータまたはJavaのイテレータは、Java文字列であることを理解し、私はScalaの文字列のリストを作成しようとしていますが、(おそらく単純)が暗黙の変換があるだろうと思っていること。

答えて

10

obj.getKeys()がjava.util.Iterator<String>だった場合、これはうまくいくはずです。私はそれがないと思う。

obj.getKeys()がちょうどjava.util.Iteratorそのままの形式ではなく、java.util.Iterator<String>ではなく、さらにjava.util.Iterator<?>であれば、これはScalaは嫌う傾向にあるものですが、とにかく、それはobj.getKeys()がStringが含まれている保証を持っていない場合はScalaはList[String]としてあなたの式を入力します方法はありません。

あなたが知っている場合は、あなたのイテレータが文字列であるが、種類はそう言っていない、あなたが唱えてもよい:

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

(当時.asScala.toListで上に行く)

注ちょうどジャワのように、そのタイプ消去のため、そのキャストはチェックされません(警告が表示されます)。あなたはすぐにあなたが文字列を持っていることを確認したい場合は、むしろあなたがリスト

+1

ありがとうございました!あなたとMatthew Farwellの大部分が同意するようです。私はあなたが何を提案したのか、obj.getKeys()。asInstanceOf [java.util.Iterator [String]]。asScala.toListこれはうまくいくように見えますが、私はコンパイルの警告を受け取りませんでした。 – rshepherd

24

あなたはそれが暗黙の型変換され、asScalaを呼び出す必要はありません。

import scala.collection.JavaConversions._ 

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

val scalaList = javaList.iterator.toList 

あなたが本当にイテレータの型パラメータを持っていない場合は、単に正しい型にキャスト:

javaList.iterator.asInstanceOf[java.util.Iterator[String]].toList 

編集:JavaConversionsでは暗黙の変換を使用しないことを好みますが、変換をより明示的にするために、JavaConvertersでasScala/asJavaデコレータを使用する方が望ましいです。

+0

正しいですが、getKeys()メソッドから返されるIteratorの型パラメータはありません。非常に鋭い観察、ありがとう。しかし、私はそこにasScalaが必要です。多分私には何かがありません。 – rshepherd

+0

暗黙的な変換は 'JavaConversions'では行われますが、' JavaConverters'では行われません。これは 'asScala'を使用します。微妙なバグを避けるために、この変換を明示的にする方が好きです。 –

+0

@ダニエル私は、物事を明示的にすることはいいアイデアだと思っています。 –

3

私は他の回答を嫌うを構築するために反復しながら、各要素のタイプをチェックします

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

を行うことができます。地獄、私はasInstanceOfを使用することを示唆しているものは嫌いです。この場合、あります。あなたがこれを行う場合:

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

あなたは、安全かつ効率的にIterator[String]Iterator[_]を回します。