2009-06-22 14 views
14

एक जावा एपीआई java.util.Map<java.lang.String,java.lang.Boolean> देता है; मैं डाल करने के लिए है कि एक Map[String,Boolean]java.util.Map से एक स्कैला मानचित्र में कनवर्ट करने के लिए कैसे करें

में तो सोच भी हमारे पास करना चाहते हैं:

var scalaMap : Map[String,Boolean] = Map.empty 
val javaMap = new JavaClass().map() // Returns java.util.Map<java.lang.String,java.lang.Boolean> 

आप Map.empty ++ javaMap ऐसा नहीं कर सकते, क्योंकि ++ विधि जावा नक्शे के बारे में पता नहीं है। मैंने कोशिश की:

scalaMap = Map.empty ++ new collection.jcl.MapWrapper[String,Boolean] { 
    override def underlying = javaMap 
} 

और:

scalaMap = Map.empty ++ new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] { 
    override def underlying = javaMap 
    } 

इन दोनों क्योंकि जेनरिक का संकलन करने, असफल - java.lang.String एक स्केला स्ट्रिंग के रूप में ही नहीं है।

क्या ऐसा करने का कोई अच्छा तरीका है, मानचित्र को मैन्युअल रूप से कॉपी करने से कम?

संपादित करें: धन्यवाद, सभी अच्छे उत्तरों, मैंने उन सभी से बहुत कुछ सीखा। हालांकि, मैंने वास्तव में मेरे पास एक साधारण समस्या पोस्ट करके गलती की है। तो, अगर तुम मुझे अनुमति देते हैं, मैं प्रश्न सामान्यीकरण होगा - क्या एपीआई वास्तव में रिटर्न

java.util.Map<java.lang.String, java.util.Map<SomeJavaEnum,java.lang.String>> 

है और मैं इस स्थानांतरित करने के लिए मैप करने की आवश्यकता [स्ट्रिंग, मानचित्र [SomeJavaEnum, स्ट्रिंग]]

यह शायद एक जटिलता की तरह प्रतीत नहीं होता है, लेकिन यह एक अतिरिक्त स्तर के प्रकार को मिटा देता है, और स्केल मैप में इसे स्थानांतरित करने का एकमात्र तरीका यह गहराई से कॉपी कर रहा था (नीचे दी गई कुछ तकनीकों का उपयोग करके)। कोई भी संकेत देता है? मैंने अपने सटीक प्रकारों के लिए एक अंतर्निहित रूपांतरण को परिभाषित करके अपनी समस्या का समाधान किया, इसलिए कम से कम कुरूपता अपने ही गुण में छिपी हुई है, लेकिन फिर भी बहुत कुछ गड़बड़ कर रही है।

+0

मुझे स्केल-उपयोगकर्ता समूह से मिलने वाले रूपांतरणों के जवाब पसंद हैं। बस यह जांचने की ज़रूरत है कि यह काम करता है ... लेकिन यह अभी बहुत देर हो चुकी है, इसलिए जल्द ही पोस्ट कर देगा ... – George

उत्तर

2

useJavaMap.scala

import test._ 
import java.lang.Boolean 
import java.util.{Map => JavaMap} 
import collection.jcl.MapWrapper 

object useJavaMap { 
    def main(args: Array[String]) { 
    var scalaMap : Map[String, Boolean] = Map.empty 
    scalaMap = toMap(test.testing()) 
    println(scalaMap) 
    } 

    def toMap[K, E](m: JavaMap[K, E]): Map[K, E] = { 
    Map.empty ++ new MapWrapper[K, E]() { 
     def underlying = m 
    } 
    } 
} 

परीक्षा/test.java

package test; 

import java.util.*; 

public class test { 
    public static Map<String, Boolean> testing() { 
     Map<String, Boolean> x = new HashMap<String, Boolean>(); 
     x.put("Test",Boolean.FALSE); 
     return x; 
    } 
    private test() {} 
} 

कमांडलाइन

javac test\test.java 
scalac useJavaMap.scala 
scala useJavaMap 
> Map(Test -> false) 
+0

न तो इन कामों से, मुझे डर है। ये जेनेरिक कक्षाएं हैं - मानचित्र [स्ट्रिंग, बूलियन] मानचित्र [java.lang.String, java.lang.Boolean] जैसा नहीं है, इसलिए आपको मिलता है: टाइप मिस्चैच; मिला: java.lang. scala.collection.jcl.MapWrapper के साथ ऑब्जेक्ट करें [स्ट्रिंग, बूलियन] \t {...} आवश्यक: मानचित्र [स्ट्रिंग, बूलियन] (पहले उदाहरण का उपयोग करके) – George

+0

में इसका प्रयास करने का समय था। पूरा नमूना प्रदान किया गया – jitter

+0

धन्यवाद, 'Map.empty ++ JMapWrapper [के, वी] (myJavaMap)' मैं चाहता हूं कि मैं चाहता हूं! –

0

मुझे लगता है कि मेरे पास आंशिक उत्तर है ...

यदि आप जावा प्रकार को जावा प्रकारों के साथ एक स्कैला मानचित्र में रूपांतरित करते हैं। इसके बाद आप स्केला प्रकार की एक स्केला नक्शे से मैप कर सकते हैं:

val javaMap = new java.util.TreeMap[java.lang.String, java.lang.Boolean] 
val temp = new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] { 
    override def underlying = javaMap 
} 
val scalaMap = temp.map{ 
    case (k, v) => (k.asInstanceOf[String] -> v.asInstanceOf[Boolean]) 
} 

इस योजना में कमी थी जिसके कारण scalaMap के प्रकार Iterable [(java.lang.String, बूलियन)] मैप नहीं है। मैं बहुत करीब महसूस करता हूं, क्या कोई इस काम को करने के लिए आखिरी वक्तव्य को ठीक करने से मेरे लिए चालाक हो सकता है ?!

6

एक स्काला String एक java.lang.Stringलेकिन एक स्काला Boolean एक java.lang.Boolean नहीं है।इसलिए निम्नलिखित कार्य:

import collection.jcl.Conversions._ 
import collection.mutable.{Map => MMap} 
import java.util.Collections._ 
import java.util.{Map => JMap} 

val jm: JMap[String, java.lang.Boolean] = singletonMap("HELLO", java.lang.Boolean.TRUE) 

val sm: MMap[String, java.lang.Boolean] = jm //COMPILES FINE 

लेकिन आपकी समस्या अभी भी Boolean अंतर के साथ समस्या है। मूल स्केला नक्शे की सामग्री के साथ साथ क्या में था जिसमें एक स्केला नक्शा है

val sm: MMap[String, Boolean] = collection.mutable.Map.empty + ("WORLD" -> false) 
val mm = (sm /: jm) { (s, t2) => s + (t2._1 -> t2._2.booleanValue) } 

फिर mm: स्काला Boolean प्रकार का उपयोग कर पुन: प्रयास करें: आप स्केला एक में "तह" करने के लिए जावा नक्शा होगा जावा मानचित्र

+0

दरअसल, आपका उत्तर परिवर्तनीय मानचित्र में परिवर्तित हो जाता है, जबकि लेखक ने अपरिवर्तनीय के लिए कहा। –

11

कम से कम स्कैला 2.9.2 के साथ संग्रह रूपांतरणों के साथ एक आसान तरीका है: आयात करें "आयात संग्रह। जावा कनवर्सन__" और "टोमैप" का उपयोग करें।

उदाहरण:

// show with Java Map: 

scala> import java.util.{Map=>JMap} 
scala> val jenv: JMap[String,String] = System.getenv() 
jenv: java.util.Map[String,String] = {TERM=xterm, ANT_OPTS=-Xmx512m ...} 

scala> jenv.keySet() 
res1: java.util.Set[String] = [TERM, ANT_OPTS...] 

// Now with Scala Map: 

scala> import collection.JavaConversions._ 
scala> val env: Map[String,String] = System.getenv.toMap // <--- TADA <--- 
env: Map[String,String] = Map(ANT_OPTS -> -Xmx512m, TERM -> xterm ...) 

// Just to prove it's got Scala functionality: 

scala> env.filterKeys(_.indexOf("TERM")>=0) 
res6: scala.collection.immutable.Map[String,String] = Map(TERM -> xterm, 
    TERM_PROGRAM -> iTerm.app, ITERM_PROFILE -> Default) 

यह बूलियन के लिए तार का एक java.util.map साथ ठीक काम करता है।