जावा में एनम के ऊपर एक 'लूप' के लिए पुनरावृति करने के लिए


875

मेरे पास enumकार्डिनल और इंटरमीडिएट निर्देशों के लिए जावा में है:

public enum Direction {
   NORTH,
   NORTHEAST,
   EAST,
   SOUTHEAST,
   SOUTH,
   SOUTHWEST,
   WEST,
   NORTHWEST
}

मैं forइन सभी enumमूल्यों के माध्यम से एक लूप कैसे लिख सकता हूं ?


जवाबों:


1400

.values()

आप values()अपने एनम पर विधि को कॉल कर सकते हैं ।

for (Direction dir : Direction.values()) {
  // do what you want
}

यह values()विधि संकलक द्वारा स्पष्ट रूप से घोषित की गई है । इसलिए यह Enumडॉक्टर पर सूचीबद्ध नहीं है ।


43
यह विधि मान क्यों () java.lang.enum के तहत यहां सूचीबद्ध नहीं है
jacktrades

80
@jacktrades: यह एक अंतर्निहित विधि है जो केवल संकलक में मौजूद है। इसलिए आधार वर्ग एक ही नाम के साथ एक विधि की घोषणा नहीं कर सकता है और इस प्रकार यह स्वचालित रूप से उत्पन्न Javadocs में शामिल नहीं होता है। docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
अजीब तरह से, यह valueOf () डॉक्स
greg7gkb

129

किसी एनम प्रकार के सभी स्थिरांक public static T[] values()उस प्रकार के निहित विधि को कॉल करके प्राप्त किए जा सकते हैं :

 for (Direction d : Direction.values()) {
     System.out.println(d);
 }

@ RAnders00 सच। लेकिन फिर भी जवाब मान्य है और प्रारूप वास्तव में कोई फर्क नहीं पड़ता (मेरे लिए कम से कम)
dARKpRINCE

क्या करता #है?
योतेंगो यूएनएलसीडी

@YoTengoUnLCD मूल रूप से यह कह रहा है कि मान () Enum ऑब्जेक्ट का हिस्सा है। जैसे Enum#values()=Enum.values()
स्पॉटलाइट

हम्म, आई एम सॉरी, मैं फॉलो नहीं करता, क्या यह .हमेशा (?) का उपयोग करने के समान है ?
योतेंगो यूएनएलसीडी

3
@YoTengoUnLCD हैशटैग जावा कोड सिंटैक्स है, न कि जावा कोड।
जेफ जी

62

आप इस प्रकार कर सकते हैं:

for (Direction direction : EnumSet.allOf(Direction.class)) {
  // do stuff
}

1
बशर्ते आप java.util.EnumSet
Nate

8
Java8 के लिए सुपर उपयोगी है लूप्स। EnumSet.allOf (Enum.class) .forEach (blah -> मेथड (blah))
Hiro2k

1
@ Hiro2k आप यह भी कर सकते हैं Arrays.stream(Enum.values()).forEach(...)- धारा अनुक्रमिक होगी
RAnders00

1
@ अच्छी तरह से, यह setइसके बजाय है array। यह "बेहतर" नहीं है, हालांकि यह मेरी राय में बेहतर मान का वर्णन करता है, क्योंकि सेट की परिभाषा से, सेट में मूल्यों को दोहराया नहीं जा सकता है (जैसे एनम में), जबकि सरणी में मान हो सकते हैं।
जेजोर

2
@ जेज़र यह एक बेहतर विकल्प है जब आपको वास्तव में बहुत तेज़ झंडों की आवश्यकता होती है, जैसे कि झंडे, हालांकि एक साधारण पुनरावृत्ति के लिए यह बहुत जटिल लगता है।
स्कैप्टन

44

स्ट्रीम

जावा 8 से पहले

for (Direction dir : Direction.values()) {
            System.out.println(dir);
}

जावा 8

हम लैम्ब्डा और स्ट्रीम का उपयोग भी कर सकते हैं ( ट्यूटोरियल ):

Stream.of(Direction.values()).forEachOrdered(System.out::println);

धाराओं के साथ क्यों forEachOrderedऔर कैसे नहीं forEach?

यदि इस धारा के प्रत्येक तत्व के लिए एक क्रिया करता है, तो धारा का एनकाउंटर क्रम में यदि एनकाउंटर एनकाउंटर ऑर्डर है, तो forEachस्पष्ट रूप से नॉनडेर्मिनिस्टिक का व्यवहार होता है forEachOrdered। इसलिए forEachगारंटी नहीं देता कि ऑर्डर रखा जाएगा।

धाराओं के साथ काम करते समय (विशेष रूप से समानांतर वाले) धाराओं की प्रकृति को ध्यान में रखें। डॉक्टर के अनुसार :

स्ट्रीम पाइपलाइन के परिणाम nondeterministic या गलत हो सकते हैं यदि धारा संचालन के लिए व्यवहारिक पैरामीटर स्टेटफुल हैं। स्टेटफुल लैम्बडा वह है जिसका परिणाम किसी भी राज्य पर निर्भर करता है जो स्ट्रीम पाइपलाइन के निष्पादन के दौरान बदल सकता है।

Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...

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

व्यवहार के मापदंडों में साइड-इफेक्ट ऑपरेशन को स्ट्रीम करने के लिए, सामान्य रूप से, हतोत्साहित होते हैं, क्योंकि वे अक्सर स्टेटलेसनेस आवश्यकता के अनजाने उल्लंघन के साथ-साथ अन्य थ्रेड-सुरक्षा खतरों का कारण बन सकते हैं।

धाराएँ एक परिभाषित मुठभेड़ आदेश हो सकती हैं या नहीं। एक स्ट्रीम के पास एनकाउंटर ऑर्डर है या नहीं, यह स्रोत और मध्यवर्ती संचालन पर निर्भर करता है।


जैसा कि सभी स्ट्रीम ऑपरेशंस में थ्रेड स्टेटलेसनेस और साइड इफेक्ट लिमिट docs.oracle.com/javase/8/docs/api/java/util/stream/… के बारे में पता होता है । इस संबंध में ये 2 enum चलना विकल्प काफी अलग हैं।
buzz3791


19

यदि आपको इस आदेश की परवाह नहीं है तो यह काम करना चाहिए:

Set<Direction> directions = EnumSet.allOf(Direction.class);
for(Direction direction : directions) {
    // do stuff
}

2
बशर्ते आप java.util.EnumSet और java.util.Set आयात करें
Nate

4
के लिए दस्तावेज़ीकरण सेEnumSet : पुनरावृत्तक द्वारा पुनरावृत्ती विधि उनके प्राकृतिक क्रम में तत्वों का पता लगाती है (जिस क्रम में एनम स्थिरांक घोषित किए जाते हैं) । यह गारंटी देता है कि पुनरावृत्ति का क्रम उसके द्वारा दिए गए आदेश से मेल खाता है Enum.values()
जेफ जी


5

Java8

Stream.of(Direction.values()).forEach(System.out::println);

Java5 + से

for ( Direction d: Direction.values()){
 System.out.println(d);
}

1
मुझे माफ करें। मुझे बस एहसास हुआ कि akhil_mittal ने पहले ही इसी तरह का उत्तर पोस्ट किया था।
रघु के नायर

मुझे कब और क्यों Stream.of (o) का उपयोग करना चाहिए? लूप के लिए अधिक पठनीय लगता है।
जेरेमी

यदि आप कार्यात्मक प्रोग्रामिंग से परिचित नहीं हैं।
एलेक्सिस डुफ्रेनॉय

5

प्रत्येक के लिए उपयोग करने का प्रयास करें

for ( Direction direction : Direction.values()){
  System.out.println(direction.toString());
}

4

जावा 8 में अधिक विधियाँ:

के EnumSetसाथ उपयोग कर रहा हैforEach

EnumSet.allOf(Direction.class).forEach(...);

के Arrays.asListसाथ उपयोग कर रहा हैforEach

Arrays.asList(Direction.values()).forEach(...);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.