2011-09-28 4 views
13

Lütfen benimle oynayın, Scala ile hala oldukça noobish yaşıyorum.java.util.Iterator?

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

obj.getKeys docs göre (ithal edilmektedir) JavaConverers aracılığıyla

asScala çağrılması bir java.util.Iterator döndürür ..

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

: Aşağıdaki kod var scala.collection.Iterator ancak buradan

def toList : List[A] 

Bu yüzden bu, çalışması gerektiğini inanıyordu bu dayalı tanımlar Burada derleme hatası var.

[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 

Ben tür parametresi veya java Yineleyici bir Java dize anlıyorum ve Scala dizeleri bir liste oluşturmak için çalışıyorum, ancak (belki safça) örtük bir dönüşüm olacağını düşündüm.

cevap

10

Bu, eğer obj.getKeys() öğesi java.util.Iterator<String> ise işe yarar. Sanırım değil. obj.getKeys() Eğer

sadece java.util.Iterator değil java.util.Iterator<String> ham formda, hatta java.util.Iterator<?> olduğunu, bu şey skala olduğu beğenmeme eğiliminde, ama yine de, bu obj.getKeys() String içerir garanti varsa hiçbir şekilde scala List[String] olarak ifade yazacaktır var . Eğer yineleyici Strings olduğunu biliyorum ama tip bunu söylemek etmezse

, sen dökme olabilir:

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

(daha sonra .asScala.toList ile devam)

Not, o sadece java gibi ve tip silme nedeniyle, bu döküm kontrol edilmeyecektir (bir uyarı alacaksınız). Eğer hemen Dizeleri olduğunu kontrol etmek istiyorsanız, yerine listeyi

+1

Cevabınız için çok teşekkürler! Görünüşe göre sen ve Matthew Farwell çoğunlukla katılıyorum. Önerdiğin şeyi yaptım, obj.getKeys(). AsInstanceOf [java.util.Iterator [String]] .Scala.toList ve bu işe yaradı ve bir derleme uyarısı almadım. – rshepherd

24
Sen asScala aramaya gerek yok

, bir örtük dönüştürme olur :

import scala.collection.JavaConversions._ 

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

val scalaList = javaList.iterator.toList 

gerçekten yineleyici türü parametresi yoksa, sadece doğru türe döküm:

DÜZENLEME: Bazı kullanıcılar JavaConversions'daki örtük dönüşümleri kullanmamayı tercih eder, ancak dönüşümleri daha açık hale getirmek için JavaConverters'daki asScala/asJava dekoratörlerini kullanır.

+0

Haklısınız, yineleyici için getKeys() yönteminden döndürülen bir tür parametresi yoktur. Çok akıllı gözlem, teşekkürler. Görünüşe rağmen, oradaki asScala'ya ihtiyacım var. Belkide eksik olduğum başka bir şey var. – rshepherd

+0

Kapalı dönüşüm, "JavaConversters" üzerindedir, ancak "JavaConverters" üzerinde değildir. Bu "ascala" kullanır. Kendim dahil birçok kişi, bu hataları açıklıktan korumak için bu dönüşümü açıkça yapmayı tercih ediyor. –

+0

@Daniel Açıkça şeyler yapmak iyi bir fikirdir, bahşiş için teşekkürler. –

3

diğer cevaplar sevmediğim inşa etmek yineleme sırasında her öğenin türünü kontrol edecektir

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

yapabilirsiniz. Cehennem, alternatifi olmadığı sürece asInstanceOf kullanmayı öneren hiçbir şeyi sevmiyorum. Bu durumda, var. Bunu yaparsanız:

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

güvenle ve verimli bir Iterator[String] içine Iterator[_] açın.

İlgili konular