2008-10-27 11 views
21

निम्नलिखित जावा enum को देखते हुए:कैसे() ओवरराइड toString साथ enum की स्ट्रिंग परिणाम कन्वर्ट करने के लिए वापस enum के लिए?

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
      return "18 - 23"; 
     } 
    }, 
    A24TO29 { 
     public String toString() {   
      return "24 - 29"; 
     } 
    }, 
    A30TO35 { 
     public String toString() {   
      return "30 - 35"; 
     } 
    }, 

} 

वहाँ किसी भी तरह से की एक स्ट्रिंग मान परिवर्तित करने के लिए है - इसी enum मूल्य अर्थात AgeRange.A18TO23 करने के लिए "18 23"?

धन्यवाद!

उत्तर

30

के एक दस्तावेज हिस्सा यह इस तरह है करने के लिए सबसे अच्छा और आसान तरीका है:

public enum AgeRange { 
    A18TO23 ("18-23"), 
    A24TO29 ("24-29"), 
    A30TO35("30-35"); 

    private String value; 

    AgeRange(String value){ 
     this.value = value; 
    } 

    public String toString(){ 
     return value; 
    } 

    public static AgeRange getByValue(String value){ 
     for (final AgeRange element : EnumSet.allOf(AgeRange.class)) { 
      if (element.toString().equals(value)) { 
       return element; 
      } 
     } 
     return null; 
    } 
} 

फिर आपको इनपुट के साथ getByValue() विधि का आह्वान करने की आवश्यकता है इस में।

+1

मैं मानता हूं कि मूल्य को कन्स्ट्रक्टर में रखना अच्छा लगता है।बहुत बड़े enums के लिए (और वे वास्तव में बहुत बड़ा होना होगा) यह एक मानचित्र का उपयोग करने के लिए समझ में आता है। मैं व्यक्तिगत रूप से पाश अंदर से रूप में अच्छी तरह वापसी चाहते हैं, लेकिन फिर मैं "एक ही स्थान पर पठनीयता की परवाह किए बिना से वापसी" की :) –

+0

एक अन्य बिंदु एक प्रशंसक कभी नहीं किया गया है - यह बजाय EnumSet.allOf उपयोग करने के लिए बेहतर होगा AgeRange.values ​​() के रूप में अन्यथा आप प्रत्येक कॉल के लिए एक नई सरणी बनाते हैं। –

+0

मैं आपके साथ जॉन स्कीट से सहमत हूं :) बदल रहा है ... – sakana

7

तुम हमेशा मूल्य के लिए स्ट्रिंग से एक नक्शा बना सकते हैं - तो स्थिर करना है ताकि आप केवल एक बार यह मैप करने के लिए, यह सोचते हैं कि लौट आए स्ट्रिंग समय के साथ ही रहता है की जरूरत है। जहां तक ​​मुझे पता है वहां कुछ भी अंतर्निहित नहीं है।

+0

यह इस संभाल करने के लिए एक बेहतर तरीका है। नक्शा तब बनाया जाता है जब enum होता है, और एक सरणी को फिर से चलाने से बहुत तेज संचालन करता है। –

+0

मैं इस विधि पर भी विचार कर रहा हूं, लेकिन मेरे पास इस enum में केवल 15 मान हैं। क्या नक्शा बनाने के लिए यह अभी भी अधिक कुशल है? – Walter

+0

शायद ईमानदार होने के लिए नहीं। हैश टेबल बड़ी मात्रा में डेटा के लिए बहुत अच्छे हैं, लेकिन मुझे संदेह है कि 15 मानों (सबसे खराब) की तुलना में हैशकोड प्राप्त करने, सही बाल्टी आदि के रूप में तेज़ होगा। –

2
for (AgeRange ar: EnumSet.allOf(AgeRange)) { 
    if (ar.toString().equals(inString)) { 
     myAnswer = ar; 
     break; 
    } 
} 

या ऐसा कुछ? बस टाइप किया गया है, एक कंपाइलर के माध्यम से नहीं चला है। (पर टिप्पणी) लिखने की त्रुटियों ...

माफ कर दो या फिर इस तरह के तर्क का उपयोग एक बार एक नक्शा बनाने के लिए। रनटाइम पर पुनरावृत्ति से बचें। अच्छा विचार, जॉन।

2

कक्षा "toString()" ओवरराइड करता है - इसलिए, रिवर्स ऑपरेशन प्राप्त करने के लिए, आपको toString() के आउटपुट को एनम मानों के आउटपुट का अनुवाद करने के लिए valueOf() ओवरराइड करने की आवश्यकता है।

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
       return "18 - 23"; 
     } 
     public AgeRange valueOf (Class enumClass, String name) { 
       return A18T023 
     } 
    }, 

    . 
    . 
    . 
} 

क्रेता सावधान रहना - uncompiled और untested ...

तंत्र toString() के लिए और valueOf()API

+0

क्या यह दूसरा मूल्य हो सकता है विधि के लिए? – iny

+0

[iny] बिल्कुल सही है - प्रतिबिंबित करने के लिए संपादित। –

+2

-1 अगर मैं गलत नहीं हूँ, valueOf यहाँ के बारे में सलाह है ... गलत, कोमल होने के लिए ;-)। 'valueOf()' स्थिर है, और किसी विशेष enum मान के शरीर में कोई उपयोग नहीं है। और यहां तक ​​कि यह सब ठीक होने के बाद भी, "सही" कार्यान्वयन गलत होगा, जिसमें संकलक 'स्थैतिक सार्वजनिक मूल्य (स्ट्रिंग)' पर स्थिर ओवरराइड की अनुमति नहीं देता है। सामान्य फिक्स केवल 'valueOf' का उपयोग नहीं करना है - एक अलग नाम का उपयोग करें। –

0

आप निम्नलिखित की तरह कुछ की कोशिश कर सकते?

static AgeRange fromString(String range) { 
    for (AgeRange ageRange : values()) { 
     if (range.equals(ageRange.toString())) { 
      return ageRange; 
     } 
    } 
    return null; 
} 

या, के रूप में दूसरों का सुझाव दिया, एक कैशिंग दृष्टिकोण का उपयोग कर:

private static Map<String, AgeRange> map; 

private static synchronized void registerAgeRange(AgeRange ageRange) { 
    if (map == null) { 
     map = new HashMap<String, AgeRange>(); 
    } 
    map.put(ageRange.toString(), ageRange); 
} 

AgeRange() { 
    registerAgeRange(this); 
} 

static AgeRange fromString(String range) { 
    return map.get(range); 
} 
4

प्रभावी जावा (2 एड) मद 30 के अनुसार, यह हो सकता है (यह बहुत तेजी से पाश से है)

public enum AgeRange { 
     A18TO23("18-23"), 
     A24TO29("24-29"), 
     A30TO35("30-35"); 

     private final String value; 

     AgeRange(String value){ 
      this.value = value; 
     } 

     @Override public String toString(){ 
      return value; 
     } 

     private static final Map<String, AgeRange> stringToEnum = 
      new HashMap<String, AgeRange>(); 

     static { 
      for (AgeRange r : values()) { 
       stringToEnum.put(r.toString(), r); 
      } 
     } 

     public static AgeRange getByValue(String value){ 
      return stringToEnum.get(value); 
     } 
} 
संबंधित मुद्दे