एक कथन में एक बार में एक HashMap में कई प्रविष्टियाँ जोड़ना


138

मुझे एक निरंतर HashMap को इनिशियलाइज़ करने की आवश्यकता है और इसे एक लाइन स्टेटमेंट में करना चाहेंगे। इस तरह से sth से बचना:

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));

उद्देश्य सी में इसके समान:

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 

मुझे ऐसा कोई उदाहरण नहीं मिला है जो यह दर्शाता हो कि ऐसा करने का तरीका इतने सारे लोगों को दिखता है।

जवाबों:


258

तुम यह केर सकते हो:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};

11
@ user387184 हाँ, वे इसे "डबल ब्रेस इनिशलाइज़र" कहते हैं। इस विषय को देखें: stackoverflow.com/questions/924285/…
Eng.Fouad

2
मैं इसे अपने कोड में डाल देता हूं और मुझे यह चेतावनी / संदेश लाइन में मिलता है: "धारावाहिक योग्य वर्ग किसी प्रकार के लंबे समय के स्थिर अंतिम serialVersionUID क्षेत्र की घोषणा नहीं करता है"। क्या मैं बस इसे अनदेखा कर सकता हूँ? इसका क्या मतलब है? धन्यवाद
user387184

31
आपको इस विधि का उपयोग नहीं करना चाहिए। यह जो है हर बार है कि आप इसे उपयोग करते हैं, के लिए एक नया वर्ग पैदा ज्यादा सिर्फ स्पष्ट रूप से एक नक्शा बनाने से भी बदतर प्रदर्शन। देखें stackoverflow.com/questions/924285/…
टिमो तुर्शमन

7
इसका कारण यह है कि मैंने इसे समझा दिया क्योंकि यह हर बार आपके द्वारा उपयोग किए जाने के लिए एक नया वर्ग बनाता है। मुझे लगता है कि लोगों को इसे इस तरह से करने के व्यापार के बारे में पता होना चाहिए।
इगुनगोटनोसन

6
@ TimoTürschmann लगता है कि अगर मुझे कभी भी इस तरह के नक्शे के स्थैतिक आरंभ की आवश्यकता होती है, कि यह स्थिर भी होगा, तो हर बार जब आप इसे प्रदर्शन दंड का उपयोग करते हैं, तो आप उस दंड को एक बार समाप्त कर देंगे। मैं किसी भी अन्य समय को नहीं देख सकता कि कोई इस तरह के आरंभीकरण के बिना वैरिएबल स्थिर हो (उदाहरण के लिए, क्या कोई कभी लूप में उपयोग करेगा?)। मैं गलत हो सकता हूं, हालांकि, प्रोग्रामर आविष्कारशील हैं।
क्रिस सरीफाइस

65

आप Google Guava के ImmutableMap का उपयोग कर सकते हैं। यह तब तक काम करता है जब तक आप बाद में मानचित्र को संशोधित करने की परवाह नहीं करते (आप इस विधि का उपयोग करके इसे बनाने के बाद नक्शे पर .put () को कॉल नहीं कर सकते):

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();

इसे भी देखें: http://docs.guava-lbooks.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

कुछ हद तक संबंधित प्रश्न: मैप्स में हैशमैप के लिए ImmutableMap.of () वर्कअराउंड?


अमरूद बहुत बड़ा है, मैं जब तक बिल्कुल जरूरी अपने Android एप्लिकेशन के लिए इसका उपयोग नहीं होगा
ericn

4
कुंजियों या मूल्यों को ImmutableMapस्वीकार नहीं करता है कि खबरदार null
वडज़िम

@ericn ProGuard आपको उस लाइब्रेरी के किसी भी हिस्से को बाहर करने देता है जिसका आप उपयोग नहीं कर रहे हैं।
21o में dimo414

55

जावा 9 के बाद से, इसका उपयोग करना संभव है Map.of(...), जैसे:

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);

यह नक्शा अपरिवर्तनीय है। यदि आप चाहते हैं कि मानचित्र परस्पर परिवर्तित हो, तो आपको जोड़ना होगा:

Map<String, Integer> hashMap = new HashMap<>(immutableMap);

यदि आप जावा 9 का उपयोग नहीं कर सकते हैं, तो आप अपने लिए एक समान सहायक विधि लिखने या आपके लिए उस कार्यक्षमता को जोड़ने के लिए एक तृतीय-पक्ष लाइब्रेरी (जैसे अमरूद ) का उपयोग करने के साथ फंस गए हैं।


10 प्रविष्टियों को जोड़ने के बाद, यह अजीब त्रुटि फेंकता है "विधि को हल नहीं कर सकता है", क्या यह विधि इस बग के साथ है?
विक्रमवी

2
@vikramvi हां अगर आप डॉक्यूमेंटेशन Map.of को देखते हैं तो यह केवल 10 प्रविष्टियों तक किया जाता है क्योंकि यह काफी श्रमसाध्य है
jolivier

8

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

यदि आपको उस प्रकार के सिंटैक्स की आवश्यकता है, तो कुछ ग्रूवी पर विचार करें, जो जावा-संगत है और आपको करने देता है:

def map = [name:"Gromit", likes:"cheese", id:1234]

8

जावा 9 में नक्शों के कारखाने भी शामिल हैं। 10 प्रविष्टियों के लिए मैप्स में ओवरलोडेड कंस्ट्रक्टर हैं जो कुंजियों और मूल्यों के जोड़े लेते हैं। उदाहरण के लिए हम विभिन्न शहरों और उनकी आबादी (अक्टूबर 2016 में Google के अनुसार) का एक नक्शा बना सकते हैं:

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);

Map के लिए var-args का मामला थोड़ा कठिन है, आपको कुंजी और मान दोनों चाहिए, लेकिन Java में, विधियों में दो var-args पैरामीटर नहीं हो सकते। तो सामान्य मामले को Map.Entry<K, V>ऑब्जेक्ट्स के एक var-args विधि को ले कर और entry()उन्हें बनाने वाली स्थैतिक विधि को जोड़कर नियंत्रित किया जाता है । उदाहरण के लिए:

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);

जावा 9 में संग्रह कारखाने के तरीके


यदि आप जावा 9+ का उपयोग कर सकते हैं तो बहुत बढ़िया। इसके अलावा इन कारखाने विधि अपरिवर्तनीय नक्शा देता है।
सौरभ

6

यहां एक सरल वर्ग है जो आप चाहते हैं कि पूरा करेगा

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}

और फिर इसका उपयोग करने के लिए

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);

यह प्रदान करता है {a:1, b:2}


4
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

की घोषणा को अनदेखा करना x(जो एक "अप्राप्य कथन" निदान से बचने के लिए आवश्यक है), तकनीकी रूप से यह केवल एक बयान है।


14
यह घृणित हैकी है।
मीका सीढ़ियाँ

1
@MicahStairs - लेकिन यह केवल एक बयान है।
गर्म लंड

2
यह सच है, लेकिन यह उस तरह का कोड है जिसकी मैं कभी भी उत्पादन में ठोकर खाने की उम्मीद नहीं करता।
मीका सीढ़ियों

@MicahStairs - मैंने बदतर देखा है।
हॉट लिक्स

1
ओमग मैं ने आज इसके लिए खोज की है, यह कोड कैसे काम करता है? मैंने इसे परीक्षण के लिए कोड में जोड़ दिया है, लेकिन मैं इसका पता नहीं लगा सकता कि यह आंतरिक रूप से कैसे काम करता है ... :)
GOXR3PLUS

1

आप इस उपयोगिता फ़ंक्शन को उपयोगिता वर्ग में जोड़ सकते हैं:

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    for (int index = 0; index < keyValues.length / 2; index++) {
        map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
    }

    return map;
}

Map<Integer, String> map1 = YourClass.mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = YourClass.mapOf("key1", "value1", "key2", "value2");

नोट: Java 9आप Map.of का उपयोग कर सकते हैं


-1

एक अन्य दृष्टिकोण नियमित अभिव्यक्ति द्वारा एक स्ट्रिंग से सभी तत्वों के मूल्यों को निकालने के लिए विशेष फ़ंक्शन लिख सकता है:

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
    public static void main (String[] args){
        HashMap<String,Integer> hashMapStringInteger = createHashMapStringIntegerInOneStat("'one' => '1', 'two' => '2' , 'three'=>'3'  ");

        System.out.println(hashMapStringInteger); // {one=1, two=2, three=3}
    }

    private static HashMap<String, Integer> createHashMapStringIntegerInOneStat(String str) {
        HashMap<String, Integer> returnVar = new HashMap<String, Integer>();

        String currentStr = str;
        Pattern pattern1 = Pattern.compile("^\\s*'([^']*)'\\s*=\\s*>\\s*'([^']*)'\\s*,?\\s*(.*)$");

        // Parse all elements in the given string.
        boolean thereIsMore = true;
        while (thereIsMore){
            Matcher matcher = pattern1.matcher(currentStr);
            if (matcher.find()) {
                returnVar.put(matcher.group(1),Integer.valueOf(matcher.group(2)));
                currentStr = matcher.group(3);
            }
            else{
                thereIsMore = false;
            }
        }

        // Validate that all elements in the given string were parsed properly
        if (currentStr.length() > 0){
            System.out.println("WARNING: Problematic string format. given String: " + str);
        }

        return returnVar;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.