2011-09-28 25 views
13

請耐心等待,我對Scala仍然很不在意。我有以下代碼:java.util.Iterator到Scala列表?

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

obj.getKeys根據文檔返回java.util.Iterator的

調用asScala,經由JavaConverers(其被導入)..

java.util.Iterator <==> scala.collection.Iterator 

scala.collection.Iterator的定義

def toList : List[A] 

因此,基於這個我相信這應該工作,howev呃這裏是編譯錯誤。

[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字符串,我想創建斯卡拉字符串列表,但是(也許天真地)認爲會有一個隱式轉換。

回答

10

如果obj.getKeys()是java.util.Iterator<String>,那麼這將起作用。我想這不是。

如果obj.getKeys()只是java.util.Iterator原始形式,不java.util.Iterator<String>,甚至沒有java.util.Iterator<?>,這是後話斯卡拉往往不喜歡的,但是反正有辦法斯卡拉沒有將鍵入您的表達List[String]如果它不能保證obj.getKeys()包含字符串。

如果你知道你的迭代器是字符串,但類型不會這麼說,你可投:

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

(然後再與.asScala.toList

需要注意的是,就像在Java並且由於類型擦除,該演員陣容不會被檢查(您會收到警告)。如果你想馬上你有一個字符串檢查,你可能寧願做

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

當你迭代,以生成列表

+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

@Daniel我想讓東西明確是一個好主意,謝謝你的提示。 –

3

我不喜歡其他的答案,這將檢查每個元素的類型。地獄,我不喜歡任何暗示使用asInstanceOf,除非沒有其他選擇。在這種情況下,有。如果你這樣做:

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

您打開Iterator[_]Iterator[String]安全和有效。