software - Java.util.Properties को हैश मैप<स्ट्रिंग, स्ट्रिंग> में कनवर्ट करना




java verify (8)

आप Google Guava का उपयोग कर सकते हैं:

com.google.common.collect.Maps.fromProperties(Properties)

Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?

java.util.Properties मानचित्र का एक कार्यान्वयन है, और हैश मैप कन्स्ट्रक्टर को मानचित्र प्रकार परम प्राप्त होता है। लेकिन स्पष्ट रूप से क्यों परिवर्तित करना चाहिए?


इस बारे में कैसा है?

   Map properties = new Properties();
   Map<String, String> map = new HashMap<String, String>(properties);

चेतावनी का कारण बन जाएगा, लेकिन पुनरावृत्तियों के बिना काम करता है।


ऐसा करने का एक प्रभावी तरीका सिर्फ एक सामान्य मानचित्र पर डालना है:

Properties props = new Properties();

Map<String, String> map = (Map)props;

यह एक Map<Object, Object> को कच्चे मानचित्र में परिवर्तित करेगा, जो कंपाइलर (केवल चेतावनी) के लिए "ठीक है" है। एक बार हमारे पास कच्चा Map यह Map<String, String> जो यह "ठीक" होगा (एक और चेतावनी)। आप एनोटेशन @SuppressWarnings({ "unchecked", "rawtypes" }) साथ उन्हें अनदेखा कर सकते हैं @SuppressWarnings({ "unchecked", "rawtypes" })

यह काम करेगा क्योंकि JVM में ऑब्जेक्ट में वास्तव में एक सामान्य प्रकार नहीं है। सामान्य प्रकार केवल एक चाल है जो संकलन समय पर चीजों की पुष्टि करता है।

अगर कुछ कुंजी या मान स्ट्रिंग नहीं है तो यह ClassCastException त्रुटि उत्पन्न करेगा। वर्तमान Properties कार्यान्वयन के साथ यह होने की संभावना बहुत कम है, जब तक आप सुपर Hashtable<Object,Object> Properties से म्यूटेबल कॉल विधियों का उपयोग नहीं करते हैं।

इसलिए, यदि आपके गुणों के उदाहरण के साथ बुरा काम नहीं करते हैं तो यह जाने का तरीका है।


जावा 8 रास्ता:

properties.entrySet().stream().collect(
    Collectors.toMap(
         e -> e.getKey().toString(),
         e -> e.getValue().toString()
    )
);

मैं निम्नलिखित Guava API का उपयोग करूंगा: com.google.common.collect.Maps#fromProperties

Properties properties = new Properties();
Map<String, String> map = Maps.fromProperties(properties);

यदि आप जानते हैं कि आपकी Properties ऑब्जेक्ट में केवल <String, String> प्रविष्टियां हैं, तो आप कच्चे प्रकार का सहारा ले सकते हैं:

Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>((Map) properties);

समस्या यह है कि Properties Map<Object, Object> लागू करता है, जबकि HashMap Map<? extends String, ? extends String> कन्स्ट्रक्टर Map<? extends String, ? extends String> अपेक्षा करता है Map<? extends String, ? extends String> Map<? extends String, ? extends String> Map<? extends String, ? extends String>

यह उत्तर यह बताता है (काफी प्रतिद्वंद्वी) निर्णय। संक्षेप में: जावा 5 से पहले, Properties ने Map लागू किया था (क्योंकि वहां कोई जेनरिक नहीं था)। इसका मतलब था कि आप किसी Object को किसी Object में डाल सकते हैं। यह अभी भी दस्तावेज में है:

चूंकि Properties putAll से प्राप्त होते हैं, इसलिए put और putAll विधियों को Properties ऑब्जेक्ट पर लागू किया जा सकता है। उनका उपयोग दृढ़ता से निराश होता है क्योंकि वे कॉलर को उन प्रविष्टियों को सम्मिलित करने की अनुमति देते हैं जिनकी चाबियाँ या मान String एस नहीं हैं। इसके बजाय setProperty विधि का उपयोग किया जाना चाहिए।

इसके साथ संगतता बनाए रखने के लिए, डिजाइनरों के पास जावा 5 में Map<Object, Object> वारिस करने के अलावा कोई अन्य विकल्प नहीं था। यह पूर्ण पिछड़ा संगतता के लिए प्रयास का दुर्भाग्यपूर्ण परिणाम है जो नए कोड को अनावश्यक रूप से बंद कर देता है।

यदि आप कभी भी अपनी Properties ऑब्जेक्ट में स्ट्रिंग गुणों का उपयोग करते हैं, तो आप अपने कन्स्ट्रक्टर में एक अनचेक कास्ट से दूर हो सकते हैं:

Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);

या बिना किसी प्रतियां:

Map<String, String> map = (Map<String, String>) properties;

Properties Map<Object, Object> लागू करता है - Map<String, String> नहीं Map<String, String>

आप इस कन्स्ट्रक्टर को कॉल करने की कोशिश कर रहे हैं:

public HashMap(Map<? extends K,? extends V> m)

... K और V दोनों String रूप में।

लेकिन Map<Object, Object> Map<? extends String, ? extends String> नहीं है Map<? extends String, ? extends String> Map<? extends String, ? extends String> Map<? extends String, ? extends String> ... इसमें गैर-स्ट्रिंग कुंजी और मान हो सकते हैं।

यह काम करेगा:

Map<Object, Object> map = new HashMap<Object, Object>();

... लेकिन यह आपके लिए उतना उपयोगी नहीं होगा।

मूल रूप से, Properties को कभी भी HashTable उप-वर्ग नहीं बनाया जाना चाहिए ... यह समस्या है। V1 के बाद से, यह इरादे के खिलाफ होने के बावजूद, हमेशा गैर-स्ट्रिंग कुंजी और मानों को स्टोर करने में सक्षम रहा है। यदि इसके बजाय संरचना का उपयोग किया गया था, तो एपीआई केवल स्ट्रिंग कुंजी / मानों के साथ काम कर सकता था, और सब ठीक रहे होंगे।

आप ऐसा कुछ चाहते हैं:

Map<String, String> map = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
    map.put(key, properties.getProperty(key));
}




java