जावा में किसी HashMap को एक शून्य कुंजी या मान जोड़ने का क्या उपयोग है?


91

HashMap एक अशक्त कुंजी और किसी भी शून्य मान की अनुमति देता है। इसका क्या उपयोग है?


11
"शायद समस्या यह नहीं है कि कुछ भी हमें परेशान नहीं कर रहा है, लेकिन हम इसे परेशान कर रहे हैं।"
bmargulies

3
गुवा, गूगल संग्रह में, कई वर्ग अशक्त होने की अनुमति नहीं देते हैं और इसके पीछे तर्क यह है कि 95% मामलों में अशक्त होने की आवश्यकता नहीं है और वे बग का प्रतिनिधित्व कर सकते हैं, संभवतः इसे खोजने के लिए मुश्किल है।
stivlo

अजीब बात यह है, कि ConcurrentHashMapशून्य-कुंजियों का समर्थन नहीं करता है, जबकि HashMapकरता है।
कोडप्लेब

2
केवल हाशपैप शून्य की अनुमति देता है :)
सुभाषियों

जवाबों:


126

मैं सकारात्मक नहीं हूं कि आप क्या पूछ रहे हैं, लेकिन अगर आप एक उदाहरण के लिए देख रहे हैं कि कोई कब एक अशक्त कुंजी का उपयोग करना चाहेगा, तो मैं डिफ़ॉल्ट मामले का प्रतिनिधित्व करने के लिए नक्शे में अक्सर उनका उपयोग करता हूं (अर्थात उस मूल्य का उपयोग किया जाना चाहिए यदि कोई दी गई कुंजी मौजूद नहीं है):

Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);

HashMapनल कुंजियों को विशेष रूप से संभालता है (क्योंकि यह .hashCode()एक अशक्त वस्तु पर कॉल नहीं कर सकता है ), लेकिन शून्य मान कुछ विशेष नहीं हैं, वे मानचित्र में कहीं और संग्रहीत हैं


4
तो अगर .hashCode () अशक्त पर संभव नहीं है, जो यह तय करता है कि कौन सी गाड़ी नल कुंजी दर्ज करेगी?
17

26
@ स्पेसर इसमें HashMap( putForNullKey) एक विशेष विधि है जो इसे संभालती है; यह इसे टेबल 0 में स्टोर करता है
माइकल मूरजेक

1
@MichaelMrozek आपकी अंतिम पंक्ति B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);मुझे लगता है कि हम बस खोज कुंजी पर विधि प्राप्त कर सकते हैं जिसका एक ही परिणाम होगा। B val = foo.get(search);अगर मुझे कुछ गलत हो रहा है तो क्या आप मुझे सही कर सकते हैं?
धीरजराज

6
@ dheeraj92 यदि कुंजी मौजूद नहीं है तो आपका कोड सेट valहो जाएगा null; मेरा इसे nullनक्शे में जो भी नक्शे में सेट करता है । यह बिंदु था, मैं nullमानचित्र में कुंजी पर एक डिफ़ॉल्ट गैर-शून्य मान संग्रहीत करता हूं और इसका उपयोग करता हूं यदि वास्तविक कुंजी मौजूद नहीं है
माइकल Mrozek

28

एक उदाहरण पेड़ों के मॉडलिंग के लिए होगा। यदि आप एक ट्री संरचना का प्रतिनिधित्व करने के लिए एक HashMap का उपयोग कर रहे हैं, जहां कुंजी माता-पिता है और मूल्य बच्चों की सूची है, तो nullकुंजी के लिए मान रूट नोड होंगे।


6

null मूल्यों के लिए उपयोग का एक उदाहरण HashMapमहंगे ऑपरेशन के परिणामों के लिए कैश के रूप में उपयोग करना है (जैसे कि बाहरी वेब सेवा पर कॉल) जो वापस आ सकता है null

nullमानचित्र में एक मूल्य डालकर आप उस मामले के बीच अंतर करने की अनुमति देते हैं जहां ऑपरेशन किसी दिए गए कुंजी ( cache.containsKey(someKey)रिटर्न false) के लिए नहीं किया गया है , और जहां ऑपरेशन किया गया है, लेकिन एक nullमान लौटा ( cache.containsKey(someKey)रिटर्न true, cache.get(someKey)रिटर्न null)।

nullमानों के बिना , आपको nullप्रतिक्रिया दर्शाने के लिए या तो कैश में कुछ विशेष मूल्य रखना होगा , या बस उस प्रतिक्रिया को कैश नहीं करना चाहिए और हर बार ऑपरेशन करना होगा।


3

अब तक के जवाब केवल एक nullकुंजी के लायक मानते हैं , लेकिन सवाल भी पूछता है any number of null values

nullहाशप में कुंजी के विरुद्ध मान को संचय करने का लाभ डेटाबेस, आदि में समान है - आप एक मान होने के बीच एक अंतर रिकॉर्ड कर सकते हैं जो खाली है (जैसे स्ट्रिंग ""), और बिल्कुल मान नहीं है (अशक्त) ।


2

यहाँ एक मामले में मेरा एकमात्र-कुछ-वंचित उदाहरण है जहाँ nullकुंजी उपयोगी हो सकती है:

public class Timer {
    private static final Logger LOG = Logger.getLogger(Timer.class);
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>();

    public static synchronized void start() {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(null)) {
            LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms"); 
        }
        START_TIMES.put(null, now);
    }

    public static synchronized long stop() {
        if (! START_TIMES.containsKey(null)) {
            return 0;
        }

        return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis());
    }

    public static synchronized void start(String name) {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(name)) {
            LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms"); 
        }
        START_TIMES.put(name, now);
    }

    public static synchronized long stop(String name) {
        if (! START_TIMES.containsKey(name)) {
            return 0;
        }

        return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis());
    }

    private static long printTimer(String name, long start, long end) {
        LOG.info(name + " timer ran for " + (end - start) + "ms");
        return end - start;
    }
}

यदि आप एक भीमकाय टाइमर को रोकने की कोशिश कर रहे हैं, या जिसे पहले ही रोक दिया गया है, तो इसे एक त्रुटि होना चाहिए, जिसे अनदेखा नहीं किया जाना चाहिए।
निधि मोनिका का मुकदमा

@QPaysTaxes - आपके इरादे पर निर्भर करता है। यदि आप एक हल्की उपयोगिता चाहते हैं जो आसानी से उपयोग की जा सके, तो आप आम तौर पर नहीं चाहते throw Exception। इसके अलावा, यह एक गैर-मौजूद या पहले से ही बंद टाइमर को रोकने का प्रयास करने जैसा नहीं है, ऐसा कुछ है जो कॉलर आमतौर पर से पुनर्प्राप्त कर सकता है।
एरोथ

1

एक अन्य उदाहरण: मैं इसे डेट के हिसाब से ग्रुप डेटा में उपयोग करता हूं। लेकिन कुछ डेटा की तारीख नहीं है। मैं इसे हेडर "NoDate" के साथ समूहित कर सकता हूं


0

एक नल कुंजी भी सहायक हो सकती है जब मैप यूआई चयन के लिए डेटा संग्रहीत करता है जहां मैप कुंजी एक बीन फ़ील्ड का प्रतिनिधित्व करता है।

यूआई चयन में "(कृपया चयन करें)" के रूप में उदाहरण के लिए एक संबंधित अशक्त फ़ील्ड मान का प्रतिनिधित्व किया जाएगा।

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