2009-11-14 12 views
10

मेरे पास निम्न की तरह एक enum क्लास है:मैं जावा में वर्णमाला के रूप में enum सदस्यों को कैसे क्रमबद्ध करूं?

public enum Letter { 
    OMEGA_LETTER("Omega"), 
    GAMMA_LETTER("Gamma"), 
    BETA_LETTER("Beta"), 
    ALPHA_LETTER("Alpha"), 

    private final String description; 

    Letter() { 
     description = toString(); 
    } 

    Letter(String description) { 
     this.description = description; 
    } 

    public String getDescription() { 
     return description; 
    } 
} 

बाद में मेरे कोड को नीचे मैं मूल रूप से पत्र enum पर पुन: सक्रिय करता हूं और अपने सदस्यों को कंसोल पर प्रिंट करता हूं:

for (Letter letter : Letter.values()) { 
System.out.println(letter.getDescription()); 
} 

मैंने सोचा कि मूल्य () विधि मुझे enum का एक आदेशित दृश्य देगी (जैसा कि वर्णित here) है, लेकिन यह मामला यहां नहीं है। मैं बस एनम सदस्यों को उस क्रम में प्राप्त करता हूं जिसे मैंने उन्हें पत्र एनम कक्षा के भीतर बनाया था। क्या वर्णमाला क्रम में enum के मानों को आउटपुट करने का कोई तरीका है? क्या मुझे एक अलग तुलनित्र वस्तु की आवश्यकता होगी, या क्या ऐसा करने का एक अंतर्निहित तरीका है? असल में मैं मानों को वर्णमाला() टेक्स्ट के आधार पर वर्णानुक्रमित क्रमबद्ध करना चाहता हूं:

Alpha 
Beta 
Gamma 
Omega 
+1

जो लेख आप लिंक करते हैं वह गलत नहीं है। वह जिस क्रम को संदर्भित करता है वह अनुक्रम है जिसमें उन्हें enum में टाइप किया गया था। कंपाइलर/रनटाइम enum मानों पर कोई विशेष सॉर्टिंग नहीं करता है। – Suppressingfire

+0

मुझे यह लिंक यहां स्टैक ओवरफ्लो में मिला और मेरे लिए काम किया। http://stackoverflow.com/a/18416259/6301287 –

उत्तर

19
SortedMap<String, Letter> map = new TreeMap<String, Letter>(); 
for (Letter l : Letter.values()) { 
    map.put(l.getDescription, l); 
} 
return map.values(); 

या सिर्फ घोषणाओं को पुन: व्यवस्थित :-)

संपादित करें: केएलई के रूप में कहे अनुसार, इस मानता है कि वर्णन enum भीतर अद्वितीय हैं।

+5

लेकिन क्यों 'मानचित्र' का उपयोग करें? चाबियों के साथ कुछ भी नहीं किया जाता है, इसलिए यह इरादे को बहुत अच्छी तरह से नहीं लेता है, है ना? 'सॉर्टेडसेट' (कार्यान्वयन 'ट्रीसेट') का उपयोग करना बेहतर होगा।लेकिन विशिष्टता जो 'सेट' (या 'मैप' की चाबियों) की विशेषता है, मूल पोस्ट में जरूरी नहीं है, इसलिए मैं एक सरल (और अधिक कुशल)' सूची 'का उपयोग करने का सुझाव देता हूं, इसके बाद' संग्रह ' .sort() 'कॉल। – KLE

+1

कुंजी को क्रमबद्ध किया जाता है, मान वापस आते हैं। सवाल बताता है: "असल में मैं मूल्यों को प्राप्त करने के लिए वर्णों को क्रमबद्ध रूप से क्रमबद्ध करना चाहता हूं:), इसलिए शायद enums को प्रिंट करना वह सब कुछ नहीं है। – meriton

+0

@meriton आपकी प्रशंसा के लिए धन्यवाद। जैसा कि मैंने अपने जवाब में टिप्पणी की है, मूल पोस्ट में "मूल्य" शब्द परिभाषित नहीं किया गया है, लेकिन मैं इसे * विवरण * फ़ील्ड के मान के रूप में समझता हूं। आपके कोड नमूने और आपकी टिप्पणी में, आप मानते हैं कि "मान" का अर्थ है 'instance'। (निश्चित रूप से, मेरे कोड में, मैं आपसे सहमत हूं, लेकिन joel_nc के लिए ???) – KLE

5

बस Arrays.sort और अपने खुद के तुलनित्र का उपयोग कर उन्हें छांटते हैं।

6

मैंने सोचा कि मूल्य() विधि मुझे enum (जैसा कि यहां बताया गया है) का आदेश दिया गया दृश्य देगा, लेकिन यह मामला यहां नहीं है। मैं बस एनम सदस्यों को उस क्रम में प्राप्त करता हूं जिसे मैंने उन्हें पत्र एनम कक्षा के भीतर बनाया था।

निश्चित रूप से, घोषणा का क्रम enums के लिए महत्वपूर्ण माना जाता है, इसलिए हमें खुशी है कि वे ठीक उसी क्रम में वापस आ गए हैं। उदाहरण के लिए, जब int i एक enum मानों का प्रतिनिधित्व करता है, तो values()[i] एनम उदाहरण खोजने के लिए एक बहुत ही सरल और कारगर तरीका है। विपरीत रूप से जाने के लिए, ordinal() विधि एक enum उदाहरण की अनुक्रमणिका देता है।

क्या वर्णमाला क्रम में enum के मानों को आउटपुट करने का कोई तरीका है? क्या मुझे एक अलग तुलनित्र वस्तु की आवश्यकता होगी, या क्या ऐसा करने का एक अंतर्निहित तरीका है? मूल रूप से मैं मान वर्णानुक्रम getDescription() पाठ के आधार पर क्रमबद्ध करना चाहते हैं:

आप क्या कहते मूल्य कुछ सामान्य रूप में enums के लिए परिभाषित नहीं है। यहां, आपके संदर्भ में, आपका मतलब getDescription() का परिणाम है।

जैसा कि आप कहते हैं, आप इन विवरणों के लिए एक तुलनात्मक बना सकते हैं।यही कारण है कि हो सकता है सही :-)


नोट सामान्य रूप में, आप इन उदाहरणों के लिए कई आदेशों की जरूरत सकता है कि:

  • घोषणा आदेश (यह सरकारी आदेश है)
  • वर्णन आदेश
  • दूसरों के रूप में की जरूरत

,

  1. प्रदर्शन के कारणों के लिए आप गणना विवरण संग्रहीत कर सकती है:

    तुम भी DescriptionComparator की धारणा एक छोटा सा धक्का सकता है।

  2. क्योंकि enums उत्तराधिकारी नहीं हो सकता है, कोड पुन: उपयोग enum वर्ग के बाहर होना चाहिए। मुझे उदाहरण हम अपने परियोजनाओं में प्रयोग करेंगे देता हूँ:

अब कोड नमूने ...

/** Interface for enums that have a description. */ 
public interface Described { 
    /** Returns the description. */ 
    String getDescription(); 
} 

public enum Letter implements Described { 
    // .... implementation as in the original post, 
    // as the method is already implemented 
} 

public enum Other implements Described { 
    // .... same 
} 

/** Utilities for enums. */ 
public abstract class EnumUtils { 

    /** Reusable Comparator instance for Described objects. */ 
    public static Comparator<Described> DESCRIPTION_COMPARATOR = 
    new Comparator<Described>() { 
     public int compareTo(Described a, Described b) { 
     return a.getDescription().compareTo(b.getDescription); 
     } 
    }; 

    /** Return the sorted descriptions for the enum. */ 
    public static <E extends Enum & Described> List<String> 
    getSortedDescriptions(Class<E> enumClass) { 
     List<String> descriptions = new ArrayList<String>(); 
     for(E e : enumClass.getEnumConstants()) { 
     result.add(e.getDescription()); 
     } 
     Collections.sort(descriptions); 
     return descriptions; 
    } 
} 

// caller code 
List<String> letters = EnumUtils.getSortedDescriptions(Letter.class); 
List<String> others = EnumUtils.getSortedDescriptions(Other.class); 

ध्यान दें कि EnumUtils में जेनेरिक कोड न केवल एक enum वर्ग के लिए काम करता है, लेकिन आपकी प्रोजेक्ट में किसी भी एनम क्लास के लिए काम करता है जो Described इंटरफ़ेस लागू करता है।

जैसा कि पहले कहा गया था, एनम्स के बाहर कोड रखने का बिंदु (जहां यह अन्यथा होगा) कोड का पुन: उपयोग करना है। यह दो enums के लिए बड़ा सौदा नहीं है, लेकिन हमारे पास हमारे प्रोजेक्ट में एक हजार से अधिक enums हैं, उनमें से कई एक ही इंटरफेस के साथ ...!

0

यहां किसी वर्ग के साथ इसे वर्गीकृत करने के लिए एक सामान्य तरीका है जिसे आप सॉर्ट कर रहे क्लास पर तुलनात्मक या कस्टम तुलनित्र बनाते हैं। मुझे ऐसे उदाहरण मिल गए हैं जहां मैं तुलना को ओवरराइड नहीं करना चाहता क्योंकि यह एक अलग उद्देश्य की सेवा करता है, आप किसी भी तरह से enums के लिए नहीं कर सकते हैं, और लगातार रैपर वर्ग बनाने एक दर्द है। आप ऐसे फ़ंक्शन में पास कर सकते हैं जो एक तुलनात्मक ऑब्जेक्ट को आउटपुट करता है जिसका उपयोग आप सॉर्टिंग उद्देश्यों के लिए करना चाहते हैं।

टू कॉम्पैरेबल फ़ंक्शन केवल सूची में प्रति तत्व (एक कस्टम तुलनित्र के लिए नहीं) कहा जाता है, इसलिए यह विशेष रूप से अच्छा है यदि कॉल कुछ वर्ग के लिए महंगा है। शून्य मान आंतरिक रूप से संभाले जाते हैं, इसलिए एक कस्टम तुलनित्र से उपयोग करना आसान है। जावा 7 के टिमसार्ट एल्गोरिदम के लिए एक कॉल एक सॉर्टेड मैप (लाल-काला पेड़ या अन्य संतुलित वृक्ष कार्यान्वयन) में ओ (लॉग एन) आवेषण का एक गुच्छा करने से काफी अधिक कुशल है। और आप किसी भी विशेष वर्ग या इंटरफेस तक ही सीमित नहीं हैं।

कई मामलों में वास्तविक दुनिया के प्रदर्शन में वृद्धि महत्वपूर्ण है। उदाहरण के लिए, आकार 100k की सूची में toString() का उपयोग करते हुए डबल्स को सॉर्ट करते समय प्रदर्शन तुलना में तुलनात्मक रूप से 5x के आसपास प्रदर्शन वृद्धि होती है।

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 
import java.util.ListIterator; 

public class GenericLetterSorter { 
    public enum Letter { 
     OMEGA_LETTER("Omega"), 
     GAMMA_LETTER("Gamma"), 
     BETA_LETTER("Beta"), 
     ALPHA_LETTER("Alpha"); 

     private final String description; 

     Letter() { 
      description = toString(); 
     } 

     Letter(String description) { 
      this.description = description; 
     } 

     public String getDescription() { 
      return description; 
     } 
    } 

public static void main(String[] args) { 
    List<Letter> list = new ArrayList<>(Arrays.asList(Letter.values())); 

    sort(list, new ToComparable<Letter>() { 
     @Override 
     public Comparable toComparable(Letter letter) { 
      // sort based on the letter's description 
      return letter == null ? null : letter.getDescription(); 
     } 
    }); 

    for (Letter letter : list) 
     System.out.println(letter == null ? null : letter.name()); 
} 

    public interface ToComparable<T, C extends Comparable<? super C>> { 
     C toComparable(T t); 
    } 

    public static <T, C extends Comparable<? super C>> void sort(List<T> list, ToComparable<T, C> function) { 
     class Pair implements Comparable<Pair> { 
      final T original; 
      final C comparable; 

      Pair(T original, C comparable) { 
      this.original = original; 
      this.comparable = comparable; 
      } 

      @Override 
      public int compareTo(Pair other) { 
       return 
        comparable == null && other.comparable == null ? 0 : 
        comparable == null ? -1 : 
        other.comparable == null ? 1 : 
        comparable.compareTo(other.comparable); 
      } 
     } 

     List<Pair> pairs = new ArrayList<>(list.size()); 
     for (T original : list) 
      pairs.add(new Pair(original, function.toComparable(original))); 

     Collections.sort(pairs); 

     ListIterator<T> iter = list.listIterator(); 
     for (Pair pair : pairs) { 
      iter.next(); 
      iter.set(pair.original); 
     } 
    } 
} 
संबंधित मुद्दे