प्रत्येक मामले में मूल्य की एक सीमा के साथ स्विच स्टेटमेंट का उपयोग करना?


91

जावा में, क्या एक स्विच स्टेटमेंट लिखना संभव है जहां प्रत्येक मामले में एक से अधिक मूल्य हैं? उदाहरण के लिए (हालांकि स्पष्ट रूप से निम्नलिखित कोड काम नहीं करेगा):

switch (num) {
    case 1 .. 5:
        System.out.println("testing case 1 to 5");
        break;
    case 6 .. 10:
        System.out.println("testing case 6 to 10");
        break;
}

मुझे लगता है कि यह उद्देश्य सी में किया जा सकता है, क्या जावा में एक समान बात है? या मैं बस का उपयोग करना चाहिए if, else ifबजाय बयान?


सादे सी में भी एक्सटेंशन जो इसके लिए अनुमति देते हैं।
अर्शजी

जवाबों:


97

जावा में उस प्रकार का कुछ भी नहीं है। सिर्फ निम्नलिखित क्यों नहीं?

public static boolean isBetween(int x, int lower, int upper) {
  return lower <= x && x <= upper;
}

if (isBetween(num, 1, 5)) {
  System.out.println("testing case 1 to 5");
} else if (isBetween(num, 6, 10)) {
  System.out.println("testing case 6 to 10");
}

1
यह महान काम करता है और सरल है। इसके अलावा, यदि आप उन सभी नंबरों का चयन करना चाहते हैं, जो आपकी ज़रूरत की सीमा में नहीं हैं, तो ((! ब्यूटेन ..., अच्छी नौकरी)।
a54studio

1
@missingfaktor मैंने आपके उत्तर की थोड़ी आलोचना की है । तो, आप शायद कुछ जवाब देना चाहेंगे। हालांकि +1।
अलेक्जेंडर मालाखोव

@ मास्टर, कृपया अपनी व्यक्तिगत स्वरूपण वरीयताओं के साथ मेरे उत्तर को संपादित न करें। यह एक उपयोगी संपादन नहीं है।
लापताफैक्टर

@missingfaktor क्षमा करें। लेकिन उस संपादन को बहुत पहले मंजूरी दे दी गई थी; मुझे यह भी याद नहीं था कि मैंने कभी ऐसा किया था।
एमसी सम्राट

76

switchबयानों के साथ आप उस तरह के व्यवहार के सबसे करीब हो सकते हैं

switch (num) {
case 1:
case 2:
case 3:
case 4:
case 5:
     System.out.println("1 through 5");
     break;
case 6:
case 7:
case 8:
case 9:
case 10:
     System.out.println("6 through 10");
     break;
}

ifकथन का उपयोग करें ।


29

अन्य विकल्प, उदाहरण के लिए, इसे विभाजित करके गणित ऑपरेशन का उपयोग कर रहा है:

switch ((int) num/10) {
    case 1:
        System.out.println("10-19");
        break;
    case 2:
        System.out.println("20-29");
        break;
    case 3:
        System.out.println("30-39");
        break;
    case 4:
        System.out.println("40-49");
        break;
    default:
        break;
}

लेकिन, जैसा कि आप देख सकते हैं कि इसका उपयोग केवल तब किया जा सकता है जब प्रत्येक मामले में सीमा तय हो।


6
यह 100 से विभाजित http स्थिति कोड के साथ अच्छी तरह से काम करता है।
स्टीफन

13

मुझे नहीं लगता कि आप जावा में ऐसा कर सकते हैं। सबसे अच्छा शर्त सिर्फ सीमा के अंतिम मामले में कोड डालना है।

switch (num) {
  case 1: case 2: case 3: case 4: case 5: 
     System.Out.Println("testing case 1 to 5");
     break;
  case 6: case 7: case 8: case 9: case 10:
     System.Out.Println("testing case 6 to 10");
     break;
  default:
     //
}

10
  case 1: case 2: case 3: case 4: case 5: 
         System.out.println("testing case 1 to 5");
         break;
  case 6: case 7: case 8: case 9: case 10:
         System.out.println("testing case 6 to 10");
         break;
  default:
         System.out.println("default"); 

9

मुझे पता है कि यह पोस्ट पुरानी है, लेकिन मेरा मानना ​​है कि यह उत्तर कुछ मान्यता के योग्य है। स्विच स्टेटमेंट से बचने की कोई आवश्यकता नहीं है। यह जावा में किया जा सकता है लेकिन स्विच स्टेटमेंट के माध्यम से, मामलों में नहीं। इसमें टर्नरी ऑपरेटरों का उपयोग करना शामिल है।

public class Solution {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());

        switch ((1 <= num && num <= 5 ) ? 0 :
                (6 <= num && num <= 10) ? 1 : 2) {

            case 0:
                System.out.println("I'm between one and five inclusive.");
                break;
            case 1:
                System.out.println("I'm between 6 and 10 inclusive.");
                break;
            case 2:
                System.out.println("I'm not between one and five or 6 and 10 inclusive.");
                break;
        }
    }
}

1
अच्छा समाधान! जावा 7 और उच्चतर के साथ आप एक स्ट्रिंग पर भी स्विच कर सकते हैं ताकि आपके मामले और भी अधिक स्व-दस्तावेजीकरण हों, जैसे, switch ((1 <= num && num <= 5 ) ? "1 .. 5" : ...और फिर case "1 .. 5":
डैनियल विडिस

@ डैनियलविडिस: मैं यह सुनिश्चित करने के लिए तार के बजाय एक एनम का उपयोग करने का सुझाव दूंगा, ताकि स्थिरता सुनिश्चित हो सके।
nmatt

@ आम तौर पर सहमत। मैं "1 .. 5" शैली वाक्य रचना के उपयोग की अनुमति देने की कोशिश कर रहा था।
डेनियल विडिस

2
@ डैनियलविडीस: निश्चित रूप से एक अच्छी बात; मैं FOM_1_TO_5 की तरह एनम कॉन्स्टेंट का नाम दूंगा। आमतौर पर श्रेणियों का एक निश्चित अर्थ होता है, और उस स्थिति में सीमा के अर्थ के अनुसार एनम स्थिरांक का नाम दिया जा सकता है।
nmatt

1
मुझे लगता है कि हम सहमत हो सकते हैं या तो विकल्प 0, 1, या 2. से बेहतर है
डैनियल विडिस

6

या आप अपने एकल मामलों का उपयोग इरादा के अनुसार कर सकते हैं और अपने डिफ़ॉल्ट केस का उपयोग रेंज निर्देश को निर्दिष्ट करने के लिए कर सकते हैं:

switch(n) {
    case 1 : System.out.println("case 1"); break;
    case 4 : System.out.println("case 4"); break;
    case 99 : System.out.println("case 99"); break;
    default :
        if (n >= 10 && n <= 15)
            System.out.println("10-15 range"); 
        else if (n >= 100 && n <= 200)
            System.out.println("100-200 range");
        else
            System.out.println("Your default case");
        break;   
}

यह वही है जो मैं हमेशा करता हूं, लेकिन मामलों के बीच एक टिप्पणी भी जोड़ देता हूं, जैसे: // 10 - 15 नीचे डिफ़ॉल्ट देखें
पेर्डी एस्टाकेल

5

यदि आप स्विच का उपयोग करना चाहते हैं तो यह कोशिश करें।

public static int range(int num){ 
    if ( 10 < num && num < 20)
        return 1;
    if ( 20 <= num && num < 30)
        return 2;
    return 3;
}

public static final int TEN_TWENTY = 1;
public static final int TWENTY_THIRTY = 2;

public static void main(String[]args){
    int a = 110;
    switch (range(a)){
        case TEN_TWENTY: 
            System.out.println("10-20"); 
            break;
        case TWENTY_THIRTY: 
            System.out.println("20-30"); 
            break;
        default: break;
    }
}

क्या आप कृपया स्पष्टीकरण भी दे सकते हैं ..?
user1140237

फंक्शन रेंज इनपुट तर्क के अनुसार कुछ मान लौटाता है, इसलिए स्विच केस क्लॉज के साथ युग्मित "वैल्यू ऑफ रेंज" का पता लगाया जा सकता है।
zl9394

यह मेरे उपयोग के मामले में काम करता है, मेरे पास 2 इंट वेरिएबल हैं और मैं जांचना चाहता हूं कि 2 वैरिएबल समान श्रेणी में हैं (10-20), (20-30), .... इस तरह
समीर काजी

मैं जादू इंट मान के बजाय एक एनम का उपयोग करने का सुझाव दूंगा।
nmatt

4

नहीं, तुम ऐसा नहीं कर सकते। सबसे अच्छा आप यह कर सकते हैं

case 1:
case 2:
case 3:
case 4:
case 5: 
  System.Out.Println("testing case 1 to 5");
break;

3

स्विच स्टेटमेंट द्वारा अनुमति के माध्यमcase से गिरावट के तंत्र का उपयोग करके एक ही बयान में कई शर्तों को समूह में करना संभव है , यह जावा ट्यूटोरियल में उल्लिखित है और अनुभाग in14.11 में पूरी तरह से निर्दिष्ट है स्विच वक्तव्य के जावा भाषा विशिष्टता

कोड का निम्नलिखित स्निपेट ट्यूटोरियल में एक उदाहरण से लिया गया था, यह प्रत्येक महीने में दिनों की संख्या (महीने 1 से 12 महीने की संख्या) की गणना करता है:

switch (month) {
    case 1: case 3: case 5:
    case 7: case 8: case 10:
    case 12:
        numDays = 31;
        break;
    case 4: case 6:
    case 9: case 11:
        numDays = 30;
        break;
    case 2:
        if (((year % 4 == 0) && 
             !(year % 100 == 0))
             || (year % 400 == 0))
            numDays = 29;
        else
            numDays = 28;
        break;
    default:
        System.out.println("Invalid month.");
        break;
}

जैसा कि आप देख सकते हैं, एक ही caseबयान में मूल्यों की एक श्रृंखला को कवर करने के लिए एक ही विकल्प है कि प्रत्येक संभावित मूल्यों को व्यक्तिगत रूप से सूचीबद्ध किया जाए, एक के बाद एक। एक अतिरिक्त उदाहरण के रूप में, यहां प्रश्न में छद्म कोड को कैसे लागू किया जाए:

switch(num) {
    case 1: case 2: case 3: case 4: case 5:
        System.out.println("testing case 1 to 5");
        break;
    case 6: case 7: case 8: case 9: case 10:
        System.out.println("testing case 6 to 10");
        break;
}

3

आप enumअपनी सीमाओं का प्रतिनिधित्व करने के लिए एक का उपयोग कर सकते हैं,

public static enum IntRange {
  ONE_TO_FIVE, SIX_TO_TEN;
  public boolean isInRange(int v) {
    switch (this) {
    case ONE_TO_FIVE:
      return (v >= 1 && v <= 5);
    case SIX_TO_TEN:
      return (v >= 6 && v <= 10);
    }
    return false;
  }

  public static IntRange getValue(int v) {
    if (v >= 1 && v <= 5) {
      return ONE_TO_FIVE;
    } else if (v >= 6 && v <= 10) {
      return SIX_TO_TEN;
    }
    return null;
  }
}

3

यहाँ जाने के लिए एक सुंदर और न्यूनतम रास्ता है

(num > 1 && num < 5) ? first_case_method() 
                     : System.out.println("testing case 1 to 5")
                     : (num > 5 && num < 7)  ? System.out.println("testing case 1 to 5") 
                     : (num > 7 && num < 8)  ? System.out.println("testing case 1 to 5") 
                     : (num > 8 && num < 9)  ? System.out.println("testing case 1 to 5") 
                     : ... 
                     : System.out.println("default");

क्या आप इसे समझा सकते हैं ?? - मुझे 'मिनी इफ्स' मिलता है, लेकिन उस आईडी के अलावा।
कामिन पल्लघि

@ टुनकी यह एक if..elseifविकल्प है जिसका उपयोग कैसकेर टर्नरी ऑपरेटर ( condition ? statementIfTrue : statementIfFalse) में किया जाता है।
विलीम

3

यह जावा 12 के रूप में समर्थित है । JEP 354 देखें । यहां कोई "रेंज" संभावनाएं नहीं हैं, लेकिन यह उपयोगी भी हो सकता है।

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);//number of letters
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}

आप इसे किलों पर भी लागू करने में सक्षम होना चाहिए। ध्यान दें कि आपके स्विच स्टेटमेंट को संपूर्ण होना चाहिए ( defaultकीवर्ड का उपयोग करना , या केस स्टेटमेंट में सभी संभावित मूल्यों का उपयोग करना)।


2

@missingfaktor का उत्तर वास्तव में सही है लेकिन थोड़ा अधिक जटिल है। कोड अधिक क्रिया है (कम से कम निरंतर अंतराल के लिए) तो यह हो सकता है, और लंबे समय तक, फ्लोट, पूर्णांक आदि के लिए अधिभार / जातियों और / या पैरामीटर की आवश्यकता होती है।

if (num < 1)
    System.Out.Println("invalid case: " + num); // you should verify that anyway
else if (num <= 5)
    System.Out.Println("1 to 5");
else if (num <= 10)
    System.Out.Println("6 to 10");
else if (num <= 42)
    System.Out.Println("11 to 42");
else    
    System.Out.Println("43 to +infinity");

3
देर से प्रतिक्रिया के लिए खेद है, मैं हाल ही में एसओ प्रतिक्रियाओं के साथ नहीं रख पा रहा हूं। मैं एक-एक करके आपकी आलोचना का जवाब दूंगा। 1. कोड थोड़ा अधिक क्रिया है, हां, और यह कुछ निरर्थक गणना भी करता है। लेकिन आईएमओ इस मामले में स्पष्टता दिखा रहा है। आपके कोड में, पिछले मामलों को याद रखना होगा क्योंकि एक सीढ़ी के माध्यम से गिरता है।
लापता

2
ओवरलोड और कास्ट की आवश्यकता के लिए, यह एक वैध आलोचना IMO नहीं है। जावा के पास संख्यात्मक प्रकारों पर अमूर्त करने का कोई समझदार तरीका नहीं है, जो जावा की सीमाओं के बारे में कहता है, इस दृष्टिकोण से अधिक है। Numयदि आप इस बिंदु को बेहतर ढंग से समझना चाहते हैं तो आप हास्केल के प्रकार-वर्ग का पता लगाना चाहते हैं ।
लापताफैक्टर

@missingfaktor 1. मुझे लगता है कि स्वाद की बात है। जब मैं निरंतर अंतराल से निपटता हूं, तो मैं व्यक्तिगत ifरूप से एस के बारे में सोचना पसंद करता हूं जैसे कि मैं धीरे-धीरे निचली व्यवस्था को बंद कर रहा हूं। इसके अलावा, एक निरर्थक संगणना एक समस्या नहीं है, लेकिन निरर्थक तुलना थोड़ी चिंताजनक है: समवर्ती से बाहर की तुलनाओं को बनाने के लिए यह सरल हो जाता है, जैसे कुछ संपादन के बाद if (isBetween(x, 1, 4)) {...} else if (isBetween(x, 6, 10)):। वैसे भी कोई बड़ी बात नहीं।
अलेक्जेंडर मालाखोव

2. सहमत - जावा की सीमा, लेकिन यह कि हमें किसके साथ काम करना है और आपके मूल कोड को विभिन्न प्रकारों के लिए दोहराया जाएगा। इस विशेष मामले में संख्या वर्ग का उपयोग करके एक समस्या को कम किया जा सकता है , हालांकि हास्केल का दृष्टिकोण बेहतर है (कभी भी हास्केल सीखने के लिए नहीं आया था, लेकिन यह सी ++ की "कॉन्सेप्ट लाइट" जैसा दिखता है। इसके अलावा, मेरा मानना ​​है कि आप का मतलब है Real, नहीं Num)।
अलेक्जेंडर मालाखोव

2

एक NavigableMapकार्यान्वयन का उपयोग करें , जैसे TreeMap

/* Setup */
NavigableMap<Integer, Optional<String>> messages = new TreeMap<>();
messages.put(Integer.MIN_VALUE, Optional.empty());
messages.put(1, Optional.of("testing case 1 to 5"));
messages.put(6, Optional.of("testing case 6 to 10"));
messages.put(11, Optional.empty());

/* Use */
messages.floorEntry(3).getValue().ifPresent(System.out::println);

उत्कृष्ट समाधान! if (messages.floorEntry(value)!=null) यदि आप एक पूर्णांक मूल्य का उपयोग करते हुए शून्य की जाँच करना नहीं भूलते हैं
Ch Vas

1
@ChVas जिस तरह से यहां नक्शा तैयार किया गया है, floorEntry()वह कभी वापस नहीं आएगा null( Integer.MIN_VALUEकुंजी को डालने से इसे रोकने का इरादा है)। लेकिन, आपके मूल्य प्रकार की परवाह किए बिना, आपको यह तय करने की आवश्यकता है कि वैध सीमा के बाहर कुंजियों को कैसे संभालना है।
एरिक्सन

0

0..100 की रेंज में इनपुट संख्या के लिए

int n1 = 75; // input value
String res; int n=0; 
int[] a ={0,20,35,55,70,85,101};

for(; n1>=a[n]; n++);
switch(6-n+1) {
  case 1: res="A"; break;
  case 2: res="B"; break;
  case 3: res="C"; break;
  case 4: res="D"; break;
  case 5: res="E"; break;
  default:res="F";
}
System.out.println(res);

0

जावा में इस प्रकार के व्यवहार का समर्थन नहीं किया जाता है। हालाँकि, यदि आपके पास कोई बड़ा प्रोजेक्ट है, जिसकी आवश्यकता है, तो अपने प्रोजेक्ट में Groovy कोड में सम्मिश्रण करने पर विचार करें। ग्रूवी कोड को बाइट कोड में संकलित किया जाता है और जेवीएम के साथ चलाया जा सकता है। मैं जिस कंपनी के लिए काम करता हूं वह ग्रूवी का उपयोग सेवा वर्ग और जावा लिखने के लिए और सब कुछ लिखने के लिए करती है।

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