java - मैं स्ट्रिंग पर क्यों नहीं बदल सकता?




string switch-statement (10)

1.7 के बाद से सीधे String उपयोग का एक उदाहरण भी दिखाया जा सकता है:

public static void main(String[] args) {

    switch (args[0]) {
        case "Monday":
        case "Tuesday":
        case "Wednesday":
            System.out.println("boring");
            break;
        case "Thursday":
            System.out.println("getting better");
        case "Friday":
        case "Saturday":
        case "Sunday":
            System.out.println("much better");
            break;
    }

}

मैं String पर क्यों नहीं बदल सकता?

क्या यह कार्यक्षमता बाद के जावा संस्करण में डाली जा रही है?

क्या कोई यह समझा सकता है कि मैं ऐसा क्यों नहीं कर सकता, जैसा कि तकनीकी तरीका जावा का switch स्टेटमेंट काम करता है?


अन्य उत्तरों ने कहा है कि यह जावा 7 में जोड़ा गया था और पिछले संस्करणों के लिए वर्कअराउंड दिया गया था। यह जवाब "क्यों" का जवाब देने का प्रयास करता है

जावा सी ++ की अत्यधिक जटिलताओं पर प्रतिक्रिया थी। इसे एक साधारण स्वच्छ भाषा के रूप में डिजाइन किया गया था।

स्ट्रिंग को भाषा में थोड़ा सा मामला संभालना पड़ा लेकिन मुझे यह स्पष्ट लगता है कि डिजाइनर कम से कम विशेष आवरण और सिंटेक्टिक चीनी की मात्रा रखने की कोशिश कर रहे थे।

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

1.0 और 1.4 के बीच भाषा स्वयं ही काफी ही रही। जावा में अधिकांश एन्हांसमेंट लाइब्रेरी तरफ थे।

यह सब जावा 5 के साथ बदल गया, भाषा काफी हद तक बढ़ा दी गई थी। आगे के संस्करण संस्करण 7 और 8 में पीछा किए गए। मुझे उम्मीद है कि इस दृष्टिकोण का परिवर्तन सी # के उदय से प्रेरित था।


एक कस्टम विधि का उपयोग करने के बजाय जावा एनम का उपयोग करके, जीबी के पोस्ट के आधार पर निम्नलिखित एक पूर्ण उदाहरण है।

ध्यान दें कि जावा एसई 7 में और बाद में आप स्विच कथन की अभिव्यक्ति में स्ट्रिंग ऑब्जेक्ट का उपयोग कर सकते हैं।

public class Main {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

      String current = args[0];
      Days currentDay = Days.valueOf(current.toUpperCase());

      switch (currentDay) {
          case MONDAY:
          case TUESDAY:
          case WEDNESDAY:
              System.out.println("boring");
              break;
          case THURSDAY:
              System.out.println("getting better");
          case FRIDAY:
          case SATURDAY:
          case SUNDAY:
              System.out.println("much better");
              break;

      }
  }

  public enum Days {

    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
  }
}

जब आप इंटेलिज का उपयोग करते हैं तो यह भी देखें:

फ़ाइल -> परियोजना संरचना -> परियोजना

फ़ाइल -> परियोजना संरचना -> मॉड्यूल

जब आपके पास एकाधिक मॉड्यूल होते हैं तो सुनिश्चित करें कि आप मॉड्यूल टैब में सही भाषा स्तर निर्धारित करते हैं।


पूर्णांक के आधार पर स्विच बहुत प्रभावशाली कोड के लिए अनुकूलित किया जा सकता है। अन्य डेटा प्रकार के आधार पर स्विच केवल () कथन की श्रृंखला में संकलित किए जा सकते हैं।

इसी कारण से सी और सी ++ केवल पूर्णांक प्रकारों पर स्विच की अनुमति देता है, क्योंकि यह अन्य प्रकारों के साथ व्यर्थ था।

सी # के डिजाइनरों ने फैसला किया कि शैली महत्वपूर्ण थी, भले ही कोई फायदा न हो।

जावा के डिजाइनरों ने स्पष्ट रूप से सी के डिजाइनरों की तरह सोचा।


बहुत सुंदर नहीं है, लेकिन जावा 6 के लिए एक और तरीका है और भालू:

String runFct = 
        queryType.equals("eq") ? "method1":
        queryType.equals("L_L")? "method2":
        queryType.equals("L_R")? "method3":
        queryType.equals("L_LR")? "method4":
            "method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);

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

बेशक आपके गणित में 'अन्य' और एक स्ट्रिंग (स्ट्रिंग) विधि के लिए एक प्रविष्टि हो सकती है, तो हो सकता है कि आप हो सकें

ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
   case MILK: lap(); break;
   case WATER: sip(); break;
   case BEER: quaff(); break;
   case OTHER: 
   default: dance(); break;
}

यह ग्रोवी में एक हवा है; मैं ग्रोवी जार को एम्बेड करता हूं और इन सभी चीजों को और अधिक करने के लिए एक groovy यूटिलिटी क्लास बनाता हूं जो मुझे जावा में करने के लिए उत्तेजित लगता है (क्योंकि मैं एंटरप्राइज़ में जावा 6 का उपयोग कर फंस गया हूं।)

it.'p'.each{
switch ([email protected]()){
   case "choclate":
     myholder.myval=(it.text());
     break;
     }}...

bugs.sun.com/bugdatabase/view_bug.do?bug_id=1223179 कम से कम 16 साल bugs.sun.com/bugdatabase/view_bug.do?bug_id=1223179 , जावा एसई 7 में String मामलों के साथ स्विच स्टेटमेंट लागू bugs.sun.com/bugdatabase/view_bug.do?bug_id=1223179 देरी के लिए एक स्पष्ट कारण प्रदान नहीं किया गया था, लेकिन इसे प्रदर्शन के साथ संभवतः किया जाना था।

जेडीके 7 में कार्यान्वयन

सुविधा अब "डी-शर्करा" प्रक्रिया के साथ javac में लागू की गई है; एक पैटर्न के बाद अधिक जटिल कोड में संकलन-समय पर घोषणाओं को विस्तारित करने के case में String स्थिरांक का उपयोग करके एक साफ, उच्च स्तरीय वाक्यविन्यास। परिणामी कोड जेवीएम निर्देशों का उपयोग करता है जो हमेशा मौजूद हैं।

String मामलों के साथ एक switch संकलन के दौरान दो स्विच में अनुवाद किया जाता है। प्रत्येक स्ट्रिंग को प्रत्येक स्ट्रिंग को एक अद्वितीय पूर्णांक-मूल स्थिति में इसकी स्थिति में चिह्नित करता है। यह पहले लेबल के हैश कोड पर स्विच करके किया जाता है। संबंधित मामला एक if कथन है जो स्ट्रिंग समानता का परीक्षण करता है; यदि हैश पर टकराव हैं, तो परीक्षण एक कैस्केडिंग है if-else-if । दूसरा स्विच मिरर है कि मूल स्रोत कोड में, लेकिन केस लेबल को उनके संबंधित पदों के साथ प्रतिस्थापित करता है। यह दो-चरणीय प्रक्रिया मूल स्विच के प्रवाह नियंत्रण को संरक्षित करना आसान बनाता है।

JVM में स्विच करता है

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

यदि स्थिरांक घने होते हैं, तो उन्हें निर्देशक पॉइंटर्स- tableswitch निर्देश की एक तालिका में एक सूचकांक (निम्नतम मूल्य घटाने के बाद) के रूप में उपयोग किया जाता है।

यदि स्थिरांक lookupswitch , तो सही केस के लिए एक बाइनरी खोज की जाती है- lookupswitch निर्देश।

String ऑब्जेक्ट्स पर एक switch को डी-शुगरिंग में, दोनों निर्देशों का उपयोग होने की संभावना है। lookupswitch केस की मूल स्थिति खोजने के लिए हैश कोड पर पहले स्विच के लिए उपयुक्त है। परिणामस्वरूप ordinal एक tableswitch लिए एक प्राकृतिक फिट है।

दोनों निर्देशों को संकलन समय पर क्रमबद्ध करने के लिए प्रत्येक मामले को आवंटित पूर्णांक स्थिरांक की आवश्यकता होती है। रनटाइम पर, जबकि O(1) tableswitch प्रदर्शन आमतौर पर tableswitch के O(log(n)) प्रदर्शन से बेहतर दिखाई देता है, इसके लिए यह निर्धारित करने के लिए कुछ विश्लेषण की आवश्यकता होती है कि तालिका स्पेस-टाइम lookupswitch को उचित ठहराने के लिए पर्याप्त घनी है या नहीं। बिल वेनेर्स ने एक महान लेख लिखा है जो अन्य जावा प्रवाह नियंत्रण निर्देशों के तहत एक अंडर-द-हूड के साथ, अधिक विस्तार से इसमें शामिल है।

जेडीके 7 से पहले

जेडीके 7 से पहले, enum एक String आधारित स्विच का अनुमान लगा सकता है। यह प्रत्येक enum प्रकार पर संकलक द्वारा उत्पन्न स्थिर valueOf विधि का उपयोग करता है। उदाहरण के लिए:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}

public class StringSwitchCase { 

    public static void main(String args[]) {

        visitIsland("Santorini"); 
        visitIsland("Crete"); 
        visitIsland("Paros"); 

    } 

    public static void visitIsland(String island) {
         switch(island) {
          case "Corfu": 
               System.out.println("User wants to visit Corfu");
               break; 
          case "Crete": 
               System.out.println("User wants to visit Crete");
               break; 
          case "Santorini": 
               System.out.println("User wants to visit Santorini");
               break; 
          case "Mykonos": 
               System.out.println("User wants to visit Mykonos");
               break; 
         default: 
               System.out.println("Unknown Island");
               break; 
         } 
    } 

} 






switch-statement