2011-09-28 7 views
13

कृपया मेरे साथ भालू, मैं अभी भी स्कैला के साथ बहुत नाराज हूं।java.util.Iterator को स्कैला सूची में?

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 

मैं समझता हूँ प्रकार पैरामीटर या जावा इटरेटर एक जावा स्ट्रिंग है, और है कि मैं स्काला स्ट्रिंग की एक सूची बनाने के लिए कोशिश कर रहा हूँ, लेकिन (शायद भोलेपन से) सोचा था कि वहाँ एक अंतर्निहित रूपांतरण होगा।

उत्तर

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 साथ पर जाने के)

ध्यान दें कि, बस जावा में के रूप में और टाइप एरर के कारण, उस कास्ट की जांच नहीं की जाएगी (आपको चेतावनी मिलेगी)। आप तुरंत कि आप स्ट्रिंग्स है की जांच करना चाहते हैं, तो आप बल्कि

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

जो प्रत्येक तत्व के प्रकार की जाँच करेगा जब तुम सूची

+1

उत्तर के लिए बहुत बहुत धन्यवाद! आपके जैसा लगता है और मैथ्यू फेरवेल अधिकांश भाग के लिए सहमत हैं। मैंने जो किया है, मैंने किया है, obj.getKeys()। AsInstanceOf [java.util.Iterator [स्ट्रिंग]]। 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 में अंतर्निहित रूपांतरणों का उपयोग नहीं करना पसंद करते हैं, लेकिन रूपांतरणों को और स्पष्ट करने के लिए जावाकॉन्टर में एस्काला/asJava सजावट का उपयोग करते हैं।

+0

आप सही हैं, Iterator के लिए कोई प्रकार पैरामीटर नहीं है जिसे getKeys() विधि से वापस किया जा रहा है। बहुत अजीब अवलोकन, धन्यवाद। हालांकि ऐसा प्रतीत होता है कि मुझे उस मामले में वहां के रूप में एस्काला की आवश्यकता है। शायद कुछ और है जो मुझे याद आ रही है। – rshepherd

+0

निहित रूपांतरण 'JavaConversions' पर है, लेकिन 'JavaConverters' पर नहीं है। वह 'asScala' का उपयोग करता है। बहुत से लोग, स्वयं शामिल हैं, इस रूपांतरण को सूक्ष्म बग से बचने के लिए स्पष्ट करना पसंद करते हैं। –

+0

@ डैनियल मुझे लगता है कि चीजों को स्पष्ट करना एक अच्छा विचार है, टिप के लिए धन्यवाद। –

3

मैं अन्य उत्तर नापसंद का निर्माण करने की पुनरावृति कर सकते हैं। नरक, मैं कुछ भी नापसंद करता हूं जो asInstanceOf का उपयोग करने का सुझाव देता है जब तक कि कोई विकल्प न हो। इस मामले में, वहाँ है। आप ऐसा करते हैं:

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

आप सुरक्षित रूप से और कुशलता से एक Iterator[String] में Iterator[_] बदल जाते हैं।