EnumMap Java में SortedMap क्यों नहीं है?


9

EnumMap<K extends Enum<K>, V> जावा में संबंधित एनुम की परिभाषा स्पष्ट रूप से दी गई है, जैसा कि आप javadoc में भी देख सकते हैं:

Enum मैप्स उनकी कुंजियों के प्राकृतिक क्रम में बनाए रहते हैं (जिस क्रम में Enum constants घोषित किए जाते हैं)। यह iterators संग्रह देखा गया लौटे में दिखाई देता है ( keySet(), entrySet(), और values())।

SortedMapकुंजी प्रकार के रूप में मुझे एनम का उपयोग करने की आवश्यकता है । मैं जैसे तरीकों का उपयोग करना चाहते हैं headMap()या firstKey(), लेकिन मैं का जोड़ा cpu + स्मृति प्रदर्शन से लाभ करना चाहते EnumMapहै। एक TreeMapतरह से लगता है यहाँ बहुत ज्यादा उपरि है।

प्रश्न : क्या यह सिर्फ कार्यान्वयन में चूक गया था, क्या यह आलस्य (इससे उत्पन्न AbstractMap) था या क्या एक अच्छा कारण है कि EnumMapए नहीं है SortedMap?


ट्रीसेट के बारे में क्या?
मोहम्मद देफल्लाह

@MohammedDeifallah यह पूरी तरह से अलग है, इसकी कोई कुंजी नहीं है ... क्या आपका मतलब था TreeMap?
देहरादून

3
मैं इस मुद्दे को Openjdk के लिए खोजने में सक्षम था । यह 2005 से अभी तक खुला / अनसुलझा है। मुझे लगता है कि इसे लागू नहीं किए जाने के लिए कोई "अच्छा कारण" नहीं है।
Amongalen

1
वास्तव में त्वरित उत्तर के लिए धन्यवाद, मैंने जोड़ा है कि मुझे यहां ट्रीपैप बहुत अधिक ओवरहेड लगता है, साथ ही ओ (लॉग एन) प्रश्नों के लिए। लेकिन मेरे सवाल का भी EnumSet और SortedSet, एक ही समस्या के लिए मायने रखता है।
रॉकोड

@Amongalen: आपका उत्तर मेरे प्रश्न के उत्तर के रूप में योग्य है, भले ही यह मूल कारण का जवाब नहीं देता है, इसके अलावा "ओरेकल फॉगिंग केयर नहीं करता है"। आपके द्वारा बताए गए OpenJDK मुद्दे को भी Google ने नहीं देखा, इसलिए कम से कम यह उसी समस्या से दूसरों की मदद करेगा।
रॉकोड

जवाबों:


3

यह आपके प्राथमिक प्रश्न का उत्तर नहीं देगा (क्योंकि केवल मूल डिजाइनरों के पास इसका उत्तर है), लेकिन एक दृष्टिकोण जो मैं आप पर विचार कर रहा था, वह आपको खुद को लागू करने के लिए था। के SortedMapआधार पर एक कार्यान्वयन करने की कोशिश करते हुए EnumMap, मैं निम्नलिखित वर्ग के साथ आया।

यह निश्चित रूप से एक त्वरित और गंदा कार्यान्वयन है (और ध्यान दें कि यह पूरी तरह से अनुपालन नहीं है SortedMap- क्योंकि दृश्य आवश्यकताओं को पूरा नहीं किया गया है), लेकिन अगर आपको एक की आवश्यकता है, तो आप इसे सुधार सकते हैं:

class SortedEnumMap<K extends Enum<K>, V> 
    extends EnumMap<K, V> 
    implements SortedMap<K, V> {

    private Class<K> enumClass;
    private K[] values;

    public SortedEnumMap(Class<K> keyType) {
        super(keyType);
        this.values = keyType.getEnumConstants();
        this.enumClass = keyType;

        if (this.values.length == 0) {
            throw new IllegalArgumentException("Empty values");
        }
    }

    @Override
    public Comparator<? super K> comparator() {
        return Comparator.comparingInt(K::ordinal);
    }

    @Override
    public SortedMap<K, V> subMap(K fromKey, K toKey) {
        List<K> keys = Arrays.stream(this.values)
                .dropWhile(k -> k.ordinal() < fromKey.ordinal())
                .takeWhile(k -> k.ordinal() < toKey.ordinal())
                .collect(Collectors.toList());

        return this.forKeys(keys);
    }

    @Override
    public SortedMap<K, V> headMap(K toKey) {
        List<K> keys = new ArrayList<>();

        for (K k : this.values) {
            if (k.ordinal() < toKey.ordinal()) {
                keys.add(k);
            } else {
                break;
            }
        }

        return this.forKeys(keys);
    }

    @Override
    public SortedMap<K, V> tailMap(K fromKey) {
        List<K> keys = new ArrayList<>();

        for (K k : this.values) {
            if (k.ordinal() >= fromKey.ordinal()) {
                keys.add(k);
            }
        }

        return this.forKeys(keys);
    }

    //Returned map is NOT a "view" or the current one
    private SortedEnumMap<K, V> forKeys(List<K> keys) {
        SortedEnumMap<K, V> n = new SortedEnumMap<>(this.enumClass);
        keys.forEach(key -> n.put(key, super.get(key)));

        return n;
    }

    @Override
    public K firstKey() {
        return this.values[0];
    }

    @Override
    public K lastKey() {
        return this.values[this.values.length - 1];
    }
}

और एक त्वरित परीक्षण के लिए (बग अभी तक पाया जाना है):

SortedMap<Month, Integer> m = new SortedEnumMap(Month.class);

for (Month v : Month.values()) {
    m.put(v, v.getValue());
}

System.out.println("firstKey():       " + m.firstKey());
System.out.println("lastKey():        " + m.lastKey());
System.out.println("headMap/June:     " + m.headMap(Month.JUNE));
System.out.println("tailMap/June:     " + m.tailMap(Month.JUNE));
System.out.println("subMap/April-July " + m.subMap(Month.APRIL, Month.JULY));

मुझे मिला:

firstKey():       JANUARY
lastKey():        DECEMBER
headMap/June:     {JANUARY=1, FEBRUARY=2, MARCH=3, APRIL=4, MAY=5}
tailMap/June:     {JUNE=6, JULY=7, AUGUST=8, SEPTEMBER=9, OCTOBER=10, NOVEMBER=11, DECEMBER=12}
subMap/April-July {APRIL=4, MAY=5, JUNE=6}

1
आप टिप्पणी करते हैं कि "लौटा हुआ नक्शा" एक "दृश्य" या वर्तमान एक नहीं है ", लेकिन ये विधियाँ (सिर / उप / पूंछ-मानचित्र) अवश्य देखें।
assylias

1
मैं देखता हूं कि आपके प्रश्नों में से कोई भी वास्तव में मेरे प्राथमिक प्रश्न का उत्तर नहीं है, लेकिन आपका उत्तर इस समस्या वाले अन्य लोगों के लिए कम से कम बहुत मददगार होगा, इसलिए मैं आपको आपके प्रयासों का श्रेय दूंगा। हो सकता है कि Oracle में कोई इसे पढ़ेगा और
खींचेगा

@assylias यह सही है, और मैंने पोस्ट में इसका स्पष्ट उल्लेख किया है
ernest_k

एक क्रमबद्ध नक्शा जो उन सभी कार्यों को कार्यान्वित करता है, जिसका उद्देश्य क्रमबद्ध प्रकृति का दोहन करना है, रैखिक खोजों के माध्यम से ...
होलकर

3

सुविधा अनुरोध खोलें

मैं OpenJDK के लिए इस मुद्दे को खोजने में सक्षम था । यह 2005 से अभी तक खुला / अनसुलझा है।

मुझे लगता है कि इसे लागू नहीं किए जाने के लिए कोई "अच्छा कारण" नहीं है।


इसे करने के लिए आपका धन्यवाद। इस बीच मैंने ernest_k का उत्तर देखा है जो वास्तव में मेरे प्रश्न का उत्तर नहीं देता है, लेकिन मेरे प्रश्न को अंतर्निहित समस्या के लिए एक अच्छा समाधान लाता है। मुझे खेद है कि मैंने आपको क्रेडिट नहीं दिया जैसा कि मैंने पहले उल्लेख किया है, लेकिन मुझे लगता है कि ernest_k काम के लिए इसके हकदार हैं।
रॉकोड

@ क्रोड जो पूरी तरह से समझ में आता है। अगर मैं तुम होते तो मैं भी ernest_k के उत्तर को स्वीकार कर लेता - यह मेरी तुलना में अधिक मददगार है।
Amongalen
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.