Java Enum Methods - विपरीत दिशा एनम लौटें


113

मैं एक एनम डायरेक्शन की घोषणा करना चाहता हूं, जिसमें एक तरीका है जो विपरीत दिशा देता है (निम्नलिखित सिंटैक्टिक रूप से सही नहीं है, यानी, एनमों को त्वरित नहीं किया जा सकता है, लेकिन यह मेरी बात को दिखाता है)। क्या जावा में यह संभव है?

यहाँ कोड है:

public enum Direction {

     NORTH(1),
     SOUTH(-1),
     EAST(-2),
     WEST(2);

     Direction(int code){
          this.code=code;
     }
     protected int code;
     public int getCode() {
           return this.code;
     }
     static Direction getOppositeDirection(Direction d){
           return new Direction(d.getCode() * -1);
     }
}

बस एक स्विच का उपयोग करें। आपके पास केवल 4 मामले हैं।
सोतिरियोस डेलिमोलिसिस

12
वैसे, d.getCode() * -1==-d.getCode()
tckmn

बलोच के प्रभावी जावा के अध्याय 6 (2 ई में, कम से कम) ब्याज की हो सकती है, और अत्यधिक अनुशंसित है।
जेडवर्ड

ntu.edu.sg/home/ehchua/programming/java/javaenum.html , खंड 2.1 ने अवधारणा को बड़े करीने से समझाया है
vikramvi

जवाबों:


207

शीर्षक द्वारा यहां लालच देने वालों के लिए: हां, आप अपनी खुद की विधियों को अपने ईनाम में परिभाषित कर सकते हैं। यदि आप सोच रहे हैं कि इस तरह की गैर-स्थैतिक विधि को कैसे लागू किया जाए, तो आप इसे उसी तरह करते हैं जैसे किसी अन्य गैर-स्थैतिक विधि के साथ - आप इसे उस प्रकार के उदाहरण पर लागू करते हैं जो उस पद्धति को परिभाषित या विरासत में मिलाता है। एनमों के मामले में ऐसे उदाहरण बस हैंENUM_CONSTANT एस हैं।

सब तो आप की जरूरत है EnumType.ENUM_CONSTANT.methodName(arguments)


अब सवाल से समस्या पर वापस आते हैं। समाधान का एक हो सकता है

public enum Direction {

    NORTH, SOUTH, EAST, WEST;

    private Direction opposite;

    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        EAST.opposite = WEST;
        WEST.opposite = EAST;
    }

    public Direction getOppositeDirection() {
        return opposite;
    }

}

अब Direction.NORTH.getOppositeDirection()लौटेंगे Direction.SOUTH


यहाँ @jedwards टिप्पणी को समझने के लिए थोड़ा और अधिक " हैक " किया गया है लेकिन यह अधिक फ़ील्ड जोड़ने या उनके आदेश को बदलने के बाद से पहले दृष्टिकोण के रूप में लचीला नहीं लगता है।

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

    // cached values to avoid recreating such array each time method is called
    private static final Direction[] VALUES = values();

    public Direction getOppositeDirection() {
        return VALUES[(ordinal() + 2) % 4]; 
    }
}

3
मैं एक .values()[ordinal()]हैक कोड़ा करने वाला था, लेकिन यह दृष्टिकोण बहुत अधिक मजबूत है
jedwards

आप इसका उपयोग कैसे करते हैं, हालांकि? और इस तकनीक को क्या कहा जाता है?
थफिर

1
@ तुफिर " आप इसका उपयोग कैसे करते हैं " यदि आप विधि के बारे में पूछ रहे हैं, तो किसी अन्य विधि की तरह - आप इसे इस विधि के साथ कक्षा के उदाहरण पर लागू करते हैं। के उदाहरण Directionenum वर्ग के हैं NORTH, EAST, SOUTH, WESTताकि आप केवल उपयोग कर सकते हैं NORTH.getOppositeDirection()और यह वापस आ जाएगी SOUTH। " इस तकनीक को क्या कहा जाता है? " यदि आप इसके बारे में पूछ रहे हैं static{...}तो यह स्थैतिक आरंभीकरण ब्लॉक है , यह पहली बार भरी हुई कक्षा के कोड को कोडित किया जाता है (यह उसी प्रक्रिया का हिस्सा है जो स्थैतिक क्षेत्रों को आरंभ करता है)।
Pshemo

@Phemo, मुझे आश्चर्य है कि उपरोक्त कोड का स्प्रिंग संस्करण कैसा होगा, यदि स्टैटिक ब्लॉक में जो मान सेट हो रहे हैं, उन्हें संपत्तियों की फ़ाइल से इंजेक्ट करने की आवश्यकता है।
विकास प्रसाद

161

इस तरह के एक छोटे से एनुम के लिए, मुझे सबसे अधिक पढ़ने योग्य समाधान मिलेगा:

public enum Direction {

    NORTH {
        @Override
        public Direction getOppositeDirection() {
            return SOUTH;
        }
    }, 
    SOUTH {
        @Override
        public Direction getOppositeDirection() {
            return NORTH;
        }
    },
    EAST {
        @Override
        public Direction getOppositeDirection() {
            return WEST;
        }
    },
    WEST {
        @Override
        public Direction getOppositeDirection() {
            return EAST;
        }
    };


    public abstract Direction getOppositeDirection();

}

8
महान विचार! यह तब भी अच्छा होता है जब आप आमतौर पर प्रत्येक एनुम मूल्य को एक विशिष्ट व्यवहार चाहते हैं।
OferBr

28

यह काम:

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

    public Direction oppose() {
        switch(this) {
            case NORTH: return SOUTH;
            case SOUTH: return NORTH;
            case EAST:  return WEST;
            case WEST:  return EAST;
        }
        throw new RuntimeException("Case not implemented");
    }
}

8
एक उपयुक्त क्लॉथ को फेंकने वाले एक डिफ़ॉल्ट क्लॉज को वापस करने के बजाय यह इंगित करने के लिए बेहतर हो सकता है कि एक नए जोड़े गए दिशा के लिए विपरीत को परिभाषित नहीं करने में प्रोग्रामर त्रुटि थी।
तीमुथियुस 05

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

14

एक अमूर्त विधि बनाएँ, और आपके प्रत्येक गणन मान इसे ओवरराइड करते हैं। चूंकि आप इसे बनाते समय विपरीत जानते हैं, इसलिए इसे गतिशील रूप से उत्पन्न करने या बनाने की कोई आवश्यकता नहीं है।

हालांकि यह अच्छी तरह से नहीं पढ़ता है; शायद एक switchऔर अधिक प्रबंधनीय होगा?

public enum Direction {
    NORTH(1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.SOUTH;
        }
    },
    SOUTH(-1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.NORTH;
        }
    },
    EAST(-2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.WEST;
        }
    },
    WEST(2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.EAST;
        }
    };

    Direction(int code){
        this.code=code;
    }
    protected int code;

    public int getCode() {
        return this.code;
    }

    public abstract Direction getOppositeDirection();
}

4

हाँ हम इसे हर समय करते हैं। आप एक नई वस्तु के बजाय एक स्थिर उदाहरण लौटाते हैं

 static Direction getOppositeDirection(Direction d){
       Direction result = null;
       if (d != null){
           int newCode = -d.getCode();
           for (Direction direction : Direction.values()){
               if (d.getCode() == newCode){
                   result = direction;
               }
           }
       }
       return result;
 }

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

    public Direction getOppositeDirection(){
        return Direction.values()[(this.ordinal() + 2) % 4];
    }
}

Enums में एक स्थिर मान विधि होती है जो एक सरणी देता है जिसमें एनम के सभी मानों को क्रम में रखा जाता है। स्रोत

चूंकि NORTH को 1, EAST को 2, SOUTH को 3, WEST को 4 मिलता है; आप विपरीत प्राप्त करने के लिए एक सरल समीकरण बना सकते हैं:

(मान + २)% ४


2
इसका जवाब क्यों है? भविष्य के पाठकों, या किसी भी मामले में किसी भी स्पष्टीकरण के बिना सीखने में मदद करने के लिए आप यह कैसे उम्मीद करते हैं?
ग्राम्प्रेकटन

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन समस्या को हल करने के तरीके के बारे में अतिरिक्त संदर्भ प्रदान करता है और यह समस्या को हल करता है ताकि उत्तर के दीर्घकालिक मूल्य में सुधार हो सके। याद रखें कि आप भविष्य में पाठकों के लिए सवाल का जवाब दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है! कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें, और इस बात का संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं। यह भी उल्लेख करने के लिए चोट नहीं करता है कि यह उत्तर दूसरों की तुलना में अधिक उपयुक्त क्यों है।
इटमारजी 3

क्या टिप्पणियों के बिना कोड पढ़ना मुश्किल है? या क्या आपको कोड की 7 लाइनों के लिए एक javadoc अनन्य की आवश्यकता है?
प्रीगटन

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