खोज…


परिचय

जावा एनुम्स ( enum कीवर्ड का उपयोग करके घोषित) एक एकल वर्ग के स्थिरांक की भारी मात्रा के लिए शॉर्टहैंड सिंटैक्स हैं।

वाक्य - विन्यास

  • [सार्वजनिक / संरक्षित / निजी] enum Enum_name {// एक नई Enum की घोषणा करें।
  • ENUM_CONSTANT_1 [, ENUM_CONSTANT_2 ...]; // Enum constants की घोषणा करें। यह एनम के अंदर पहली पंक्ति होनी चाहिए, और अंत में अर्धविराम के साथ अल्पविराम से अलग होना चाहिए।
  • ENUM_CONSTANT_1 (परम) [, ENUM_CONSTANT_2 (परम) ...]; // मापदंडों के साथ एनम स्थिरांक की घोषणा करें। पैरामीटर प्रकार कंस्ट्रक्टर से मेल खाना चाहिए।
  • ENUM_CONSTANT_1 {...} [, ENUM_CONSTANT_2 {...} ...]; // ओवरराइड विधियों के साथ एनम स्थिरांक की घोषणा करें। यह तब किया जाना चाहिए जब एनम में सार विधियां हों; ऐसे सभी तरीकों को लागू किया जाना चाहिए।
  • ENUM_CONSTANT.name () // Enum स्थिरांक के नाम के साथ एक स्ट्रिंग लौटाता है।
  • ENUM_CONSTANT.ordinal () // इस गणना की क्रमिक स्थिरांक को लौटाता है, अपनी परिधि घोषणा में इसकी स्थिति, जहां प्रारंभिक स्थिरांक को शून्य का एक क्रम दिया जाता है।
  • Enum_name.values () // एक नया सरणी देता है (प्रकार Enum_name []) जिसमें हर बार उस एनम के प्रत्येक स्थिरांक को शामिल किया जाता है।
  • Enum_name.valueOf ("ENUM_CONSTANT") // ENUM_CONSTANT.name () का व्युत्क्रम - दिए गए नाम के साथ Enum स्थिरांक लौटाता है।
  • Enum.valueOf (Enum_name.class, "ENUM_CONSTANT") // पिछले एक का पर्यायवाची: ENUM_CONSTANT.name () का विलोम - दिए गए नाम के साथ Enum को निरंतर लौटाता है।

टिप्पणियों

प्रतिबंध

एनम हमेशा java.lang.Enum विस्तार करते java.lang.Enum , इसलिए एक एनम के लिए एक वर्ग का विस्तार करना असंभव है। हालांकि, वे कई इंटरफेस लागू कर सकते हैं।

सलाह & चाल

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

घोषणा करना और मूल एनम का उपयोग करना

सीम को एक सील वर्ग के लिए सिंटैक्स चीनी माना जा सकता है जो कि स्थिरांक पर केवल कई बार ज्ञात होता है, जो स्थिरांक के एक सेट को परिभाषित करता है।

विभिन्न मौसमों को सूचीबद्ध करने के लिए एक सरल एनम निम्नानुसार घोषित की जाएगी:

public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

जबकि एनम कॉन्स्टेंट को ऑल-कैप्स में होने की आवश्यकता नहीं है, यह जावा कन्वेंशन है कि कॉन्स्टेंट के नाम पूरी तरह से अपरकेस हैं, अंडरस्कोर द्वारा अलग किए गए शब्दों के साथ।


आप अपनी खुद की फाइल में एनम की घोषणा कर सकते हैं:

/**
 * This enum is declared in the Season.java file.
*/
public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

लेकिन आप इसे दूसरी कक्षा के अंदर भी घोषित कर सकते हैं:

 public class Day {

    private Season season;

    public String getSeason() {
        return season.name();
    }

    public void setSeason(String season) {
        this.season = Season.valueOf(season);
    }

    /**
     * This enum is declared inside the Day.java file and 
     * cannot be accessed outside because it's declared as private.
     */
    private enum Season {
        WINTER,
        SPRING,
        SUMMER,
        FALL
    }

}

अंत में, आप एक विधि निकाय या कंस्ट्रक्टर के अंदर Enum घोषित नहीं कर सकते:

public class Day {

    /**
     * Constructor
    */
    public Day() {
        // Illegal. Compilation error
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }
    }

    public void aSimpleMethod() {
        // Legal. You can declare a primitive (or an Object) inside a method. Compile!
        int primitiveInt = 42;

        // Illegal. Compilation error.
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }

        Season season = Season.SPRING;
    }
    
}

डुप्लीकेट एनम स्थिरांक की अनुमति नहीं है:

public enum Season {
    WINTER,
    WINTER, //Compile Time Error : Duplicate Constants
    SPRING,
    SUMMER,
    FALL
} 

एनम का हर स्थिरांक public , static और डिफ़ॉल्ट रूप से final होता है। जैसा कि प्रत्येक स्थिरांक static , उन्हें सीधे एनम नाम का उपयोग करके एक्सेस किया जा सकता है।

Enum स्थिरांक विधि मापदंडों के रूप में चारों ओर पारित किया जा सकता है:

public static void display(Season s) {
    System.out.println(s.name());  // name() is a built-in method that gets the exact name of the enum constant
}

display(Season.WINTER);  // Prints out "WINTER"

आप values() पद्धति का उपयोग करके एनम स्थिरांक की एक सरणी प्राप्त कर सकते हैं। मान की गारंटी दी गई सरणी में घोषणा क्रम में होने की गारंटी है:

Season[] seasons = Season.values();

नोट: यह विधि हर बार जब इसे कहा जाता है तो मूल्यों की एक नई सरणी आवंटित करता है।


एनम स्थिरांक पर पुनरावृति करने के लिए:

public static void enumIterate() {
    for (Season s : Season.values()) {
        System.out.println(s.name());
    }
}

आप एक switch स्टेटमेंट में एनम का उपयोग कर सकते हैं:

public static void enumSwitchExample(Season s) {
    switch(s) {
        case WINTER:
            System.out.println("It's pretty cold");
            break;
        case SPRING:
            System.out.println("It's warming up");
            break;
        case SUMMER:
            System.out.println("It's pretty hot");
            break;
        case FALL:
            System.out.println("It's cooling down");
            break;
    }
}

आप == का उपयोग करके भी एनम स्थिरांक की तुलना कर सकते हैं:

Season.FALL == Season.WINTER    // false
Season.SPRING == Season.SPRING  // true

एनम स्थिरांक की तुलना करने का एक अन्य तरीका नीचे के equals() का उपयोग करके equals() , जिसे बुरा अभ्यास माना जाता है क्योंकि आप आसानी से इस प्रकार के नुकसान में पड़ सकते हैं:

Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error

इसके अलावा, हालाँकि, enum में इंस्टेंस के सेट को रन-टाइम में नहीं बदला जा सकता है, लेकिन इंस्टेंसेस स्वयं स्वाभाविक रूप से अपरिवर्तनीय नहीं हैं क्योंकि किसी भी अन्य वर्ग की तरह, एक enum में उत्परिवर्तित फ़ील्ड शामिल हो सकते हैं जैसा कि नीचे दिखाया गया है।

public enum MutableExample {
    A,
    B;

    private int count = 0;

    public void increment() {
        count++;
    }

    public void print() {
        System.out.println("The count of " + name() + " is " + count);
    }
}

// Usage:
MutableExample.A.print();       // Outputs 0
MutableExample.A.increment();
MutableExample.A.print();       // Outputs 1 -- we've changed a field   
MutableExample.B.print();       // Outputs 0 -- another instance remains unchanged

हालाँकि, एक अच्छा अभ्यास यह है कि enum इंस्टेंसेस को अपरिवर्तनीय बनाया जाए, अर्थात जब उनके पास या तो कोई अतिरिक्त फ़ील्ड नहीं है या ऐसे सभी फ़ील्ड final रूप में चिह्नित हैं और स्वयं अपरिवर्तनीय हैं। इस एप्लिकेशन को किसी की जीवन भर के लिए यह सुनिश्चित करेंगे कि enum किसी भी स्मृति लीक नहीं होगा और यह सब धागे भर में अपने उदाहरणों का उपयोग करने के लिए सुरक्षित है।


Enums परोक्ष लागू Serializable और Comparable क्योंकि Enum वर्ग करता है:

public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable

कंस्ट्रक्टरों के साथ एनम

एक enum में एक सार्वजनिक निर्माता नहीं हो सकता है; हालाँकि, निजी निर्माणकर्ता स्वीकार्य हैं (एनम के लिए निर्माता डिफ़ॉल्ट रूप से पैकेज-निजी हैं ):

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
    // note that the above parentheses and the constructor arguments match
    private int value;

    Coin(int value) { 
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

यह अनुशंसा की जाती है कि आप सभी क्षेत्रों को निजी रखें और गेट्टर के तरीके प्रदान करें, क्योंकि एक एनुम के लिए कई उदाहरण हैं।


यदि आप इसके बजाय एक Enum को एक class रूप में लागू करते हैं, तो यह इस तरह दिखेगा:

public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
    public static final Coin PENNY = new Coin(1);
    public static final Coin NICKEL = new Coin(5);
    public static final Coin DIME = new Coin(10);
    public static final Coin QUARTER = new Coin(25);

    private int value;

    private Coin(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Enum स्थिरांक तकनीकी रूप से उत्परिवर्तनीय होते हैं, इसलिए एक Enum स्थिरांक की आंतरिक संरचना को बदलने के लिए एक सेटर जोड़ा जा सकता है। हालांकि, यह बहुत बुरा अभ्यास माना जाता है और इसे टाला जाना चाहिए।

final साथ Enum क्षेत्र को अपरिवर्तनीय बनाने के लिए सबसे अच्छा अभ्यास है:

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){ 
        this.value = value;
    }

    ...

}

आप एक ही enum में कई कन्स्ट्रक्टर्स को परिभाषित कर सकते हैं। जब आप ऐसा करते हैं, तो आपके द्वारा अपनी घोषणा में पारित तर्क यह तय करते हैं कि किस निर्माता को कहा जाता है:

public enum Coin {
    PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);

    private final int value;
    private final boolean isCopperColored;

    Coin(int value){
        this(value, false);
    }

    Coin(int value, boolean isCopperColored){ 
        this.value = value;
        this.isCopperColored = isCopperColored;
    }

    ...

}

नोट: सभी गैर-आदिम Enum फ़ील्ड्स को Serializable लागू करनी चाहिए क्योंकि Enum वर्ग करता है।

विधियों और स्थिर ब्लॉकों का उपयोग करना

एक एनुम में एक विधि हो सकती है, किसी भी वर्ग की तरह। यह देखने के लिए कि यह कैसे काम करता है, हम इस तरह से एक घोषणा करेंगे:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
}

आइए एक विधि है जो उलटी दिशा में एनम लौटाते हैं:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction getOpposite(){
        switch (this){
            case NORTH:
                return SOUTH;               
            case SOUTH:
                return NORTH;                
            case WEST:
                return EAST; 
            case EAST:
                return WEST;  
            default: //This will never happen
                return null;
        }
    }
}

इसे खेतों और स्थैतिक आरम्भिक ब्लॉक के उपयोग के माध्यम से और बेहतर बनाया जा सकता है:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
    
    private Direction opposite;
    
    public Direction getOpposite(){
        return opposite;
    }
    
    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        WEST.opposite = EAST;
        EAST.opposite = WEST;
    }
}

इस उदाहरण में, विपरीत दिशा को एक निजी इंस्टेंस क्षेत्र में opposite में संग्रहीत किया जाता है, जो पहली बार एक Direction का उपयोग किया जाता है। इस विशेष मामले में (क्योंकि NORTH SOUTH और इसके विपरीत), हम यहां निर्माणकर्ताओं के साथ Enums का उपयोग नहीं कर सकते हैं (कन्स्ट्रक्टर्स NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST) अधिक सुरुचिपूर्ण होंगे और इसके opposite अनुमति देंगे final घोषित किया जाता है, लेकिन यह स्व-संदर्भ योग्य होगा और इसलिए इसकी अनुमति नहीं है)।

कार्यान्वयन इंटरफ़ेस

यह एक enum जो एक कॉल करने योग्य फ़ंक्शन भी है जो पूर्वगामी नियमित अभिव्यक्ति पैटर्न के खिलाफ String इनपुट का परीक्षण करता है।

import java.util.function.Predicate;
import java.util.regex.Pattern;

enum RegEx implements Predicate<String> {
    UPPER("[A-Z]+"), LOWER("[a-z]+"), NUMERIC("[+-]?[0-9]+");

    private final Pattern pattern;

    private RegEx(final String pattern) {
        this.pattern = Pattern.compile(pattern);
    }

    @Override 
    public boolean test(final String input) {
        return this.pattern.matcher(input).matches();
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(RegEx.UPPER.test("ABC"));
        System.out.println(RegEx.LOWER.test("abc"));
        System.out.println(RegEx.NUMERIC.test("+111"));
    }
}

एनम का प्रत्येक सदस्य विधि भी लागू कर सकता है:

import java.util.function.Predicate;

enum Acceptor implements Predicate<String> {
    NULL {
        @Override
        public boolean test(String s) { return s == null; }
    },
    EMPTY {
        @Override
        public boolean test(String s) { return s.equals(""); }
    },
    NULL_OR_EMPTY {
        @Override
        public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
    };
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Acceptor.NULL.test(null));  // true
        System.out.println(Acceptor.EMPTY.test(""));   // true
        System.out.println(Acceptor.NULL_OR_EMPTY.test(" ")); // false
    }
}

Enum बहुरूपता पैटर्न

का एक "एक्स्टेंसिबल" सेट स्वीकार करने के लिए एक विधि की जरूरत जब enum मूल्यों, प्रोग्रामर बहुरूपता की तरह एक सामान्य पर आवेदन कर सकते हैं class एक अंतरफलक जो इस्तेमाल किया anywere जहां हो जाएगा बनाने के द्वारा enum रों इस्तेमाल किया जाएगा:

public interface ExtensibleEnum {
    String name();
}

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

डिफ़ॉल्ट एनम मानों का एक सेट निम्नानुसार परिभाषित किया जा सकता है:

public enum DefaultValues implements ExtensibleEnum {
    VALUE_ONE, VALUE_TWO;
}

अतिरिक्त मान तब इस तरह परिभाषित किए जा सकते हैं:

public enum ExtendedValues implements ExtensibleEnum {
    VALUE_THREE, VALUE_FOUR;
}

नमूना जो शो कैसे enums उपयोग करने के लिए - टिप्पणी कैसे printEnum() दोनों से मान स्वीकार enum प्रकार:

private void printEnum(ExtensibleEnum val) {
    System.out.println(val.name());
}  

printEnum(DefaultValues.VALUE_ONE);    // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO);    // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR);  // VALUE_FOUR

नोट: यह पैटर्न आपको एनम मूल्यों को पुनर्परिभाषित करने से नहीं रोकता है, जो पहले से ही एक एनम में, किसी अन्य एनम में परिभाषित हैं। तब ये अलग-अलग मूल्य होंगे। इसके अलावा, स्विच-ऑन-एनम का उपयोग करना संभव नहीं है क्योंकि हमारे पास इंटरफ़ेस है, असली enum

सार विधियों के साथ Enums

एनम अमूर्त विधियों को परिभाषित कर सकते हैं, जिसे लागू करने के लिए प्रत्येक enum सदस्य की आवश्यकता होती है।

enum Action {
    DODGE {
        public boolean execute(Player player) {
            return player.isAttacking();
        }
    },
    ATTACK {
        public boolean execute(Player player) {
            return player.hasWeapon();
        }
    },
    JUMP {
        public boolean execute(Player player) {
            return player.getCoordinates().equals(new Coordinates(0, 0));
        }
    };

    public abstract boolean execute(Player player);
}

यह प्रत्येक enum सदस्य को किसी दिए गए ऑपरेशन के लिए अपने स्वयं के व्यवहार को परिभाषित करने की अनुमति देता है, बिना किसी प्रकार के शीर्ष-स्तरीय परिभाषा में किसी विधि पर स्विच करने के लिए।

ध्यान दें कि यह पैटर्न एक छोटा रूप है जो आमतौर पर बहुरूपता और / या इंटरफेस को लागू करने के बाद हासिल किया जाता है।

डॉक्यूमेंटिंग एनम

हमेशा enum नाम स्पष्ट नहीं होता है जो समझा जाए। एक enum दस्तावेज़ करने के लिए, मानक javadoc का उपयोग करें:

/**
 * United States coins
 */
public enum Coins {
    
    /**
     * One-cent coin, commonly known as a penny, 
     * is a unit of currency equaling one-hundredth 
     * of a United States dollar
     */
    PENNY(1),

    /**
     * A nickel is a five-cent coin equaling 
     * five-hundredth of a United States dollar
     */        
    NICKEL(5),

    /**
     * The dime is a ten-cent coin refers to 
     * one tenth of a United States dollar
     */        
    DIME(10),

    /**
     * The quarter is a US coin worth 25 cents, 
     * one-fourth of a United States dollar
     */        
    QUARTER(25);

    private int value;

    Coins(int value){ 
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

एक एनम के मूल्यों को प्राप्त करना

प्रत्येक enum वर्ग में एक अंतर्निहित स्थिर विधि नाम values() । यह विधि उस एनम के सभी मानों वाली एक सरणी देता है। मूल्यों पर पुनरावृति करने के लिए आप इस विधि का उपयोग कर सकते हैं। हालांकि यह नोट करना महत्वपूर्ण है कि यह विधि हर बार एक नई सरणी देता है जिसे इसे कहा जाता है।

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    
    /**
    * Print out all the values in this enum.
    */
    public static void printAllDays() {
        for(Day day : Day.values()) {
            System.out.println(day.name());
        }
    }
}

यदि आपको एक Set की आवश्यकता है तो आप EnumSet.allOf(Day.class) का भी उपयोग कर सकते हैं।

एक बंधे हुए प्रकार के पैरामीटर के रूप में मान लें

जब जावा में जेनेरिक के साथ एक क्लास लिखते हैं, तो यह सुनिश्चित करना संभव है कि टाइप पैरामीटर एक एनम है। चूंकि सभी एनम Enum वर्ग का विस्तार करते हैं, इसलिए निम्न सिंटैक्स का उपयोग किया जा सकता है।

public class Holder<T extends Enum<T>> {
    public final T value;

    public Holder(T init) {
        this.value = init;
    }
}

इस उदाहरण में, टाइप T एक एनम होना चाहिए।

नाम से स्थिर हो जाओ

कहते हैं कि हमारे पास एक DayOfWeek :

enum DayOfWeek {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

एक एनम एक बिल्ट-इन स्टैटिक valueOf() विधि से संकलित किया जाता है, जिसका उपयोग इसके नाम से एक स्थिरांक को देखने के लिए किया जा सकता है:

String dayName = DayOfWeek.SUNDAY.name();
assert dayName.equals("SUNDAY");

DayOfWeek day = DayOfWeek.valueOf(dayName);
assert day == DayOfWeek.SUNDAY;

डायनामिक एनम प्रकार का उपयोग करना भी संभव है:

Class<DayOfWeek> enumType = DayOfWeek.class;
DayOfWeek day = Enum.valueOf(enumType, "SUNDAY");
assert day == DayOfWeek.SUNDAY;

इन valueOf() दोनों valueOf() विधियाँ IllegalArgumentException को फेंक देंगी यदि निर्दिष्ट एनम में एक मिलान नाम के साथ एक स्थिरांक नहीं है।

अमरूद पुस्तकालय एक सहायक विधि Enums.getIfPresent() प्रदान करता है जो एक अपवाद को खत्म करने के लिए एक अमरूद Optional लौटाता है:

DayOfWeek defaultDay = DayOfWeek.SUNDAY;
DayOfWeek day = Enums.valueOf(DayOfWeek.class, "INVALID").or(defaultDay);
assert day == DayOfWeek.SUNDAY;

एकल-तत्व एनम के साथ सिंगलटन पैटर्न को लागू करें

जब किसी एनम को पहली बार संदर्भित किया जाता है, तो एनम स्थिरांक का त्वरित रूप से उपयोग किया जाता है। इसलिए, यह एकल-तत्व एनम के साथ सिंगलटन सॉफ्टवेयर डिजाइन पैटर्न को लागू करने की अनुमति देता है।

public enum Attendant {

    INSTANCE;

    private Attendant() {
        // perform some initialization routine
    }

    public void sayHello() {
        System.out.println("Hello!");
    }
}


public class Main {

    public static void main(String... args) {
        Attendant.INSTANCE.sayHello();// instantiated at this point
    }
}

जोशुआ बलोच की "प्रभावी जावा" पुस्तक के अनुसार, एकल-तत्व एनम एक सिंगलटन को लागू करने का सबसे अच्छा तरीका है। इस दृष्टिकोण के निम्नलिखित फायदे हैं:

  • धागा सुरक्षा
  • एकल तात्कालिकता की गारंटी
  • आउट-ऑफ-द-बॉक्स क्रमांकन

और जैसा कि अनुभाग के कार्यान्वयन इंटरफ़ेस में दिखाया गया है यह सिंगलटन एक या अधिक इंटरफेस भी लागू कर सकता है।

गुण (फ़ील्ड) के साथ Enum

मामले में हम अधिक जानकारी के साथ enum का उपयोग करना चाहते हैं और न केवल निरंतर मूल्यों के रूप में, और हम दो एनमों की तुलना करने में सक्षम होना चाहते हैं।

निम्नलिखित उदाहरण पर विचार करें:

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){
        this.value = value;
    }

    public boolean isGreaterThan(Coin other){
        return this.value > other.value;
    }

}

यहाँ हमने एक Enum परिभाषित किया जिसे Coin कहा जाता है जो इसके मूल्य का प्रतिनिधित्व करता है। विधि के साथ isGreaterThan हम दो enum s की तुलना कर सकते हैं:

Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;

System.out.println(penny.isGreaterThan(dime)); // prints: false
System.out.println(dime.isGreaterThan(penny)); // prints: true

स्ट्रिंग में परिवर्तित करें

कभी-कभी आप अपनी एनम को स्ट्रिंग में बदलना चाहते हैं, ऐसा करने के दो तरीके हैं।

हमारे पास मान लें:

public enum Fruit {
    APPLE, ORANGE, STRAWBERRY, BANANA, LEMON, GRAPE_FRUIT;
}

तो हम Fruit.APPLE जैसे कुछ को "APPLE" कैसे परिवर्तित करते हैं?


name() का उपयोग करके परिवर्तित name()

name() enum में एक आंतरिक विधि है जो enum के String प्रतिनिधित्व को लौटाता है, रिटर्न String वास्तव में प्रतिनिधित्व करता है कि एनम मूल्य कैसे परिभाषित किया गया था।

उदाहरण के लिए:

System.out.println(Fruit.BANANA.name());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"

का उपयोग कर परिवर्तित करें toString()

toString() डिफ़ॉल्ट रूप से , name() के समान व्यवहार करने के लिए अधिभूत है name()

हालाँकि, डेवलपर्स द्वारा इसे अधिक उपयोगकर्ता के अनुकूल String प्रिंट करने के लिए toString() की संभावना अधिक है

यदि आप अपने कोड में जाँच करना चाहते हैं, तो toString() उपयोग न करें, name() लिए बहुत अधिक स्थिर है। जब आप लॉग या स्टडआउट या कुछ और करने के लिए मूल्य को आउटपुट करने जा रहे हों तो केवल toString() उपयोग करें

डिफ़ॉल्ट रूप से:

System.out.println(Fruit.BANANA.toString());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"

ओवरराइड होने का उदाहरण

System.out.println(Fruit.BANANA.toString());      // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"

निरंतर विशिष्ट शरीर की गणना करें

एक में enum इसके बारे में एक विशेष निरंतर के लिए एक विशिष्ट व्यवहार परिभाषित करना संभव है enum जो के डिफ़ॉल्ट व्यवहार को ओवरराइड करता है enum इस तकनीक निरंतर विशिष्ट निकाय के रूप में जाना जाता है।

एक में परिभाषित कर रहे हैं - जॉन, बेन और ल्यूक - तीन पियानो छात्रों मान लीजिए enum नामित PianoClass : इस प्रकार है,

    enum PianoClass {
    JOHN, BEN, LUKE;
        public String getSex() {
            return "Male";
        }
        public String getLevel() {
            return "Beginner";
        }
    }

और एक दिन दो अन्य छात्र आते हैं - रीता और टॉम - एक सेक्स (महिला) और स्तर (इंटरमीडिएट) के साथ जो पिछले वाले से मेल नहीं खाते:

    enum PianoClass2 {
    JOHN, BEN, LUKE, RITA, TOM;
        public String getSex() {
            return "Male"; // issue, Rita is a female
        }
        public String getLevel() {
            return "Beginner"; // issue, Tom is an intermediate student
        }
    }

ताकि नए छात्रों को निरंतर घोषणा में जोड़ना, निम्नानुसार, सही नहीं है:

PianoClass2 tom = PianoClass2.TOM;
PianoClass2 rita = PianoClass2.RITA;
System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner
System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male

यह निरंतर, रीता और टॉम में से प्रत्येक के लिए एक विशिष्ट व्यवहार को परिभाषित करना संभव है, जो कि PianoClass2 डिफ़ॉल्ट व्यवहार को ओवरराइड करता है:

enum PianoClass3 {
    JOHN, BEN, LUKE,
    RITA {
        @Override
        public String getSex() {
            return "Female";
        }
    },
    TOM {
        @Override
        public String getLevel() {
            return "Intermediate";
        }
    };
    public String getSex() {
        return "Male";
    }
    public String getLevel() {
        return "Beginner";
    }
}

और अब टॉम का स्तर और रीता का लिंग वैसा ही है जैसा उन्हें होना चाहिए:

PianoClass3 tom = PianoClass3.TOM;
PianoClass3 rita = PianoClass3.RITA;
System.out.println(tom.getLevel()); // prints Intermediate
System.out.println(rita.getSex()); // prints Female

उदाहरण के लिए, कंस्ट्रक्टर का उपयोग करके सामग्री विशिष्ट शरीर को परिभाषित करने का एक और तरीका है:

enum Friend {
    MAT("Male"),
    JOHN("Male"),
    JANE("Female");
    
    private String gender;

    Friend(String gender) {
        this.gender = gender;
    }

    public String getGender() {
        return this.gender;
    }
}

और उपयोग:

Friend mat = Friend.MAT;
Friend john = Friend.JOHN;
Friend jane = Friend.JANE;
System.out.println(mat.getGender());     // Male
System.out.println(john.getGender());    // Male
System.out.println(jane.getGender());    // Female

शून्य उदाहरण एनम

enum Util {
    /* No instances */;

    public static int clamp(int min, int max, int i) {
        return Math.min(Math.max(i, min), max);
    }

    // other utility methods...
}

जिस प्रकार enum का उपयोग एकल (1 उदाहरण वर्ग) के लिए किया जा सकता है, उसका उपयोग उपयोगिता वर्गों (0 उदाहरण वर्ग) के लिए किया जा सकता है। बस एक के साथ एनम स्थिरांक की (खाली) सूची को समाप्त करना सुनिश्चित करें ;

निजी निर्माणकर्ताओं की तुलना में प्रो और कोन पर चर्चा के लिए तात्कालिकता को रोकने के लिए प्रश्न को शून्य उदाहरण देखें।

स्थिर क्षेत्रों के साथ एनम

यदि आपके ईनम वर्ग के लिए स्थिर क्षेत्र होना आवश्यक है, तो ध्यान रखें कि वे स्वयं एनम मानों के बाद बनाए गए हैं। इसका मतलब है कि, निम्न कोड NullPointerException में परिणाम देगा:

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers = new HashMap<>();

    private Example(int value) {
        integers.put(this.name(), value);
    }
}

इसे ठीक करने का एक संभावित तरीका:

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
}

स्थिर क्षेत्र को प्रारंभ न करें:

enum Example {
    ONE(1), TWO(2);

    // after initialisisation integers is null!!
    static Map<String, Integer> integers = null;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
    // !!this may lead to null poiner exception!!
    public int getValue(){
        return (Example.integers.get(this.name()));
    }
}

initialisisation:

  • Enum मान बनाएँ
    • साइड इफेक्ट putValue () के रूप में कहा जाता है कि पूर्णांक को इनिशियलाइज़ करता है
  • स्थिर मान सेट हैं
    • पूर्णांक = अशक्त; // enums के बाद निष्पादित किया जाता है ताकि पूर्णांकों की सामग्री खो जाए

Enum मानों के लिए तुलना और सम्‍मिलित करें

Enums में केवल स्थिरांक होते हैं और इसकी तुलना सीधे == की जा सकती है। तो, केवल संदर्भ की जांच की जरूरत है, करने के लिए उपयोग की कोई जरूरत नहीं .equals विधि। इसके अलावा, अगर। .equals रूप से गलत तरीके से उपयोग किया जाता है, तो NullPointerException को बढ़ा सकते हैं, जबकि == जांच में ऐसा नहीं है।

enum Day {
    GOOD, AVERAGE, WORST;
}

public class Test {

    public static void main(String[] args) {
        Day day = null;

        if (day.equals(Day.GOOD)) {//NullPointerException!
            System.out.println("Good Day!");
        }

        if (day == Day.GOOD) {//Always use == to compare enum
            System.out.println("Good Day!");
        }

    }
}

EnumSet , पूरक करने के लिए, हमारे पास EnumSet वर्ग में अलग-अलग विधियां समाहित हैं।

  • EnumSet#range : दो एंडपॉइंट्स द्वारा परिभाषित रेंज द्वारा Enum का सबसेट प्राप्त करने के लिए

  • EnumSet#of : बिना किसी सीमा के विशिष्ट EnumSet#of सेट। एकाधिक अतिभारित of तरीकों देखते हैं।

  • EnumSet#complementOf : विधि पैरामीटर में प्रदान की गई EnumSet#complementOf मानों का पूरक है जो EnumSet#complementOf सेट है

    enum Page {
       A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
    }
    
    public class Test {
    
      public static void main(String[] args) {
          EnumSet<Page> range = EnumSet.range(Page.A1, Page.A5);
    
          if (range.contains(Page.A4)) {
              System.out.println("Range contains A4");
          }
    
          EnumSet<Page> of = EnumSet.of(Page.A1, Page.A5, Page.A3);
    
          if (of.contains(Page.A1)) {
              System.out.println("Of contains A1");
          }
      }
    }
    


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow