कैसे पुनरावृत्ति के बिना hashmap से एक प्रविष्टि प्राप्त करने के लिए


172

क्या Entry<K,V>हैशपॉप से केवल एक प्राप्त करने का एक सुंदर तरीका है , बिना पुनरावृति, यदि कुंजी ज्ञात नहीं है।

जैसा कि प्रवेश के प्रवेश का आदेश महत्वपूर्ण नहीं है, क्या हम ऐसा कुछ कह सकते हैं

hashMapObject.get(zeroth_index);

हालांकि मुझे पता है कि सूचकांक विधि से ऐसा कोई अस्तित्व नहीं है।

अगर मैंने नीचे दिए गए दृष्टिकोण की कोशिश की, तो उसे अभी भी हैशमैप के सभी प्रवेश सेट प्राप्त करने होंगे

for(Map.Entry<String, String> entry : MapObj.entrySet()) {
    return entry;
}

सुझावों का स्वागत है।

संपादित करें: आवश्यकता को पूरा करने के लिए कृपया किसी अन्य डेटा संरचना का सुझाव दें।

जवाबों:


93

जेस्पर का जवाब अच्छा है। ट्रीपेज़ का उपयोग करने के लिए एक अन्य समाधान है (आपने अन्य डेटा संरचनाओं के लिए कहा है)।

TreeMap<String, String> myMap = new TreeMap<String, String>();
String first = myMap.firstEntry().getValue();
String firstOther = myMap.get(myMap.firstKey());

ट्री मैप में एक ओवरहेड है, इसलिए हैशपॉप तेज़ है, लेकिन वैकल्पिक समाधान के उदाहरण के रूप में।


या समवर्ती
SkLListMap

किसी कारण से, firstEntry()विधि इंटरफ़ेस में परिभाषित नहीं है SortedMap, लेकिन केवल में TreeMapऔर ConcurrentSkipListMap:(
जान्को

1
FirstEntry () को NavigableMap इंटरफ़ेस में परिभाषित किया गया है।
Perstlund

आह, धन्यवाद, मैंने केवल देखा SortedMap इसलिए क्योंकि इसमें firstKey()विधि थी।
जानको

251

नक्शे का आदेश नहीं दिया गया है, इसलिए 'पहली प्रविष्टि' जैसी कोई चीज नहीं है, और यही कारण है कि Map(या HashMap) पर कोई गेट-बाय-इंडेक्स विधि नहीं है ।

आप ऐसा कर सकते हैं:

Map<String, String> map = ...;  // wherever you get this from

// Get the first entry that the iterator returns
Map.Entry<String, String> entry = map.entrySet().iterator().next();

(नोट: खाली नक्शे की जांच करना)।

आपके कोड को मानचित्र में सभी प्रविष्टियाँ नहीं मिलती हैं, यह पहली प्रविष्टि के साथ तुरंत वापस लौटता है (और लूप से टूट जाता है)।

इस पहले तत्व की कुंजी और मूल्य को प्रिंट करने के लिए:

System.out.println("Key: "+entry.getKey()+", Value: "+entry.getValue());

नोट: कॉलिंग का iterator()मतलब यह नहीं है कि आप पूरे मानचित्र पर पुनरावृत्ति कर रहे हैं।


3
बस एक साइड नोट: LinkedHashMapकुंजी को उस क्रम में रखता है जिस क्रम में उन्हें डाला गया था।
मैथ्यू

2
हां, सामान्य रूप से नक्शे का आदेश नहीं दिया जाता है, लेकिन कुछ Mapकार्यान्वयन जैसे कि LinkedHashMapऔर TreeMapएक परिभाषित क्रम है। ( HashMapनहीं करता है)।
जेस्पर

1
चुने हुए उत्तर की तुलना में बेहतर उत्तर - चुने हुए उत्तर के बाद से TreeMap का उपयोग होता है जो कुंजी के प्रकार की तुलना करने की अपेक्षा करता है।
यजद

28

मुझे लगता है कि पुनरावृत्ति सबसे सरल समाधान हो सकता है।

return hashMapObject.entrySet().iterator().next();

एक और समाधान (सुंदर नहीं):

return new ArrayList(hashMapObject.entrySet()).get(0);

या अभी तक (बेहतर नहीं):

return hashMapObject.entrySet().toArray()[0];

7
दूसरे या तीसरे संस्करण का उपयोग करने का कोई कारण नहीं है। पहला एक पूरी तरह से ठीक है, अन्य दो बिना कुछ के लिए एक सरणी / सूची प्रदान करके बहुत समय बर्बाद करते हैं।
जोचिम सॉर

4
मैं सहमत हूँ, इसलिए "सुंदर नहीं" टिप्पणियाँ ;-)
कैडरियन

14

मान प्राप्त करें, इसे एक सरणी में बदलें, सरणी का पहला तत्व प्राप्त करें:

map.values().toArray()[0]

डब्ल्यू


8

आप कॉल करने से क्यों बचना चाहते हैं entrySet()यह आम तौर पर अपने स्वयं के संदर्भ के साथ एक पूरी तरह से नई वस्तु नहीं बनाता है, बल्कि केवल एक मुखौटा वस्तु प्रदान करता है। बस बोलना entrySet()काफी सस्ता ऑपरेशन है।


8

यदि आप Java 8 का उपयोग कर रहे हैं, तो यह findFirst जितना सरल है :

त्वरित उदाहरण:

Optional<Car> theCarFoundOpt = carMap.values().stream().findFirst();

if(theCarFoundOpt.isPresent()) {
    return theCarFoundOpt.get().startEngine();
}

6

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
public class IndexedMap extends HashMap {

    private List<Object> keyIndex;

    public IndexedMap() {
        keyIndex = new ArrayList<Object>();
    }

    /**
     * Returns the key at the specified position in this Map's keyIndex.
     * 
     * @param index
     *            index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException
     *             if the index is out of range (index < 0 || index >= size())
     */
    public Object get(int index) {
        return keyIndex.get(index);
    }

    @Override
    public Object put(Object key, Object value) {

        addKeyToIndex(key);
        return super.put(key, value);
    }

    @Override
    public void putAll(Map source) {

        for (Object key : source.keySet()) {
            addKeyToIndex(key);
        }
        super.putAll(source);
    }

    private void addKeyToIndex(Object key) {

        if (!keyIndex.contains(key)) {
            keyIndex.add(key);
        }
    }

    @Override
    public Object remove(Object key) {

        keyIndex.remove(key);
        return super.remove(key);
    }
}

संपादित करें: मैंने जानबूझकर इस के सामान्य पक्ष में तल्लीन नहीं किया ...


4

"बिना पुनरावृत्ति" के साथ आपका क्या मतलब है?

आप उपयोग कर सकते हैं map.entrySet().iterator().next()और आप नक्शे के माध्यम से पुनरावृत्ति नहीं करेंगे ("प्रत्येक वस्तु को छूने के अर्थ में")। आप Entry<K, V>हालांकि एक पुनरावृत्ति का उपयोग किए बिना पकड़ नहीं कर सकते । Map.Entry का Javadoc कहता है:

Map.entrySet पद्धति मानचित्र का संग्रह-दृश्य लौटाती है, जिसके तत्व इस वर्ग के हैं। मानचित्र प्रविष्टि का संदर्भ प्राप्त करने का एकमात्र तरीका इस संग्रह-दृश्य के पुनरावृति से है। ये Map.Entry ऑब्जेक्ट केवल पुनरावृत्ति की अवधि के लिए मान्य हैं।

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


4
import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

यह दृष्टिकोण काम नहीं करता क्योंकि आपने HashMap का उपयोग किया था। मुझे लगता है कि LinkedHashMap का उपयोग करना इस मामले में सही समाधान होगा।


1
LinkedHashMap में ऐसी कौन सी विधि है जो LinkedHashmap को काम करती है, कि यह कोड नहीं है?
एसएल बर्थ -

3

यह मानचित्र से एक एकल प्रविष्टि प्राप्त करेगा, जो लगभग उतना ही प्राप्त कर सकता है, जितना कि 'पहले' वास्तव में लागू नहीं होता है।

import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

2

उसी चीज़ की तलाश में यहाँ ठोकर खाई ... मुझे तब अमरूद की लाइब्रेरीIterables से क्लास की याद आई

"प्रथम" तत्व प्राप्त करने के लिए Iterables.getFirst( someMap.values(), null );:।
अनिवार्य रूप से के रूप में ही करता है Map.values().iterator().next(), लेकिन यह भी आप एक डिफ़ॉल्ट निर्दिष्ट करने की अनुमति देता है (इस मामले में अशक्त) मानचित्र में कुछ भी नहीं होना चाहिए।

Iterables.getLast( someMap.values(), null ); मैप में अंतिम तत्व देता है।

Iterables.get( someMap.values(), 7, null ); यदि मौजूद है तो मानचित्र में 7 वा तत्व लौटाता है, अन्यथा एक डिफ़ॉल्ट मान (इस मामले में अशक्त)।

याद रखें कि हालांकि हैशमैप का आदेश नहीं दिया गया है ... इसलिए Iterables.getFirstपहले आइटम को वापस करने की उम्मीद न करें जो आप वहां फेंक चुके हैं ... वैसे ही Iterables.getLastएक मैप मूल्य प्राप्त करने के लिए शायद उपयोगी है ।

यह सिर्फ उस के लिए अमरुद पुस्तकालय को जोड़ने के लायक नहीं हो सकता है, लेकिन अगर आप उस अन्य उपयोगी उपयोगिताओं में से कुछ का उपयोग कर रहे हैं ...


1

आपके EDIT के बाद, यहाँ मेरा सुझाव है:

यदि आपके पास केवल एक प्रविष्टि है, तो आप मानचित्र को एक दोहरी वस्तु से बदल सकते हैं। प्रकार के आधार पर, और आपकी प्राथमिकताएँ:

  • एक सरणी (2 मान, कुंजी और मान)
  • दो गुणों वाली एक साधारण वस्तु

0
map<string,string>m;
auto it=m.begin();//get iterator to the first element of map(m)
return m->first;//return first string(1st string in map<string,string>m)
//Incase you want the second string 
//you can use return m->second(2st string in map<string,string>m)
//if you want to iterate the whole map you can use loop
for(auto it:m)//m is a map
   cout<<it->first<<endl;

4
हालांकि यह कोड इस प्रश्न का उत्तर दे सकता है, कि यह कोड क्यों और / या इस बारे में अतिरिक्त संदर्भ प्रदान करता है कि यह प्रश्न इसके दीर्घकालिक मूल्य में सुधार करता है।
एलेक्स रीवाव जूल

1
हां, कृपया अपने कोड के साथ कुछ स्पष्टीकरण जोड़ें।
जकदेव

-3

मुझे जवाब मिला: (यह सरल है)

एक ArrayList लें और फिर उसे कास्टलिस्ट के आकार का पता लगाएं। यह रहा :

    ArrayList count = new ArrayList();
    count=(ArrayList) maptabcolname.get("k1"); //here "k1" is Key
    System.out.println("number of elements="+count.size());

यह आकार दिखाएगा। (सुझाव दें)। यह काम कर रहा है।


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