জাভা সুইচ বিবৃতি একাধিক ক্ষেত্রে


118

জাভা স্যুইচ স্টেটমেন্টের জন্য কীভাবে অনেকগুলি একাধিক কেস ব্যবহার করা যায় তা কেবল অনুসন্ধান করার চেষ্টা করছি trying আমি যা করার চেষ্টা করছি তার একটি উদাহরণ এখানে:

switch (variable)
{
    case 5..100:
        doSomething();
    break;
}

করা বনাম:

switch (variable)
{
    case 5:
    case 6:
    etc.
    case 100:
        doSomething();
    break;
}

যদি সম্ভব হয় কোন ধারণা, বা একটি ভাল বিকল্প কি?


12
দেখে মনে হচ্ছে আপনি পূর্ণসংখ্যা ব্যবহার করছেন তাই আমি মনে করি আপনি যদি জানেন যে আপনার রেঞ্জগুলি একটি নির্দিষ্ট আকারের হয় যা আপনি সর্বদা স্যুইচ করতে পারেন (ভেরিয়েবল / FIXED_SIZE_OF_RANGE) {কেস 0: ... ডিফল্ট: ব্রেক; }
পলরেহকুগেলার

উত্তর:


80

দুঃখের বিষয়, জাভাতে এটি সম্ভব নয়। আপনাকে if-elseবিবৃতি ব্যবহার করতে অবলম্বন করতে হবে ।


1
@ ফানজভা কোড এএফাইক আপনি এটি ভিবিএন.তে করতে পারেন। এখানে একটি উদাহরণ
বালা আর

1
@ ইউরিলিটভিনভ আপনি কি এটি প্রসারিত করতে চান কেন আপনি এটি ভুল বলে মনে করেন?
বালা আর

1
আমার উত্তরটি প্রমাণ করে এটি ভুল, এটি ওও এবং ভাষাটি নির্বিশেষে অন্যদের জন্য অনেকগুলি নেস্টেট if/elseif/elseস্টেটমেন্টের প্রয়োজন এমন এই সঠিক সমস্যাটি মোকাবেলার জন্য একটি পরিচিত এবং স্বীকৃত প্যাটার্ন ।

1
এই লিঙ্কগুলি ব্যবহার করে সুইচ মামলায় ওআর শর্ত পাওয়া সম্ভব ... plz এটি পরীক্ষা করে দেখুন: - stackoverflow.com/a/16706729/3946958
রবীন্দ্র কুশওয়াহ

4
ব্রো এর সম্ভাব্য ব্যবহার বিরতি ব্যবহার না করে একাধিক কেস লিখতে পারে এবং ক্ষেত্রে শেষে আপনি আপনার যুক্তি যেমন লিখতে পারেন: কেস কিছু_মূল্য: কেস কিছু_মূল্য: কেস কিছু_মূল্য: আপনি_লগিক_বয়েস_ এখানে বিরতি;
anoopbryan2

85

দ্বিতীয় বিকল্পটি পুরোপুরি ঠিক আছে। আমি নিশ্চিত না কেন একজন উত্তরদাতা বলেছিলেন যে এটি সম্ভব নয়। এটি ঠিক আছে, এবং আমি সর্বদা এটি করি:

switch (variable)
{
    case 5:
    case 6:
    etc.
    case 100:
        doSomething();
    break;
}

50
প্রশ্নকর্তা বলেছেন এটি এটি করা "বনাম" করুন। তিনি বুঝতে পেরেছেন যে আপনি তালিকাভুক্ত যা বৈধ তা তিনি প্রথমে এটি করার চেষ্টা করেছিলেন।
ব্লেইন মাক্লো

45
আমি দুঃখিত, তবে আমি দেখতে পাচ্ছি না যে একই জিনিসগুলিতে একের পর এক 95 টি কেস তালিকাবদ্ধ করা কোনও কিছুর সমাধান। যদি আমি মুখোমুখি হয়েছি যে কোনও কোডেই আমি সেগুলি ট্র্যাক করব, তাদের কিডন্যাপ করব, ব্যক্তিগতভাবে তাদের GLaDOS এ পৌঁছে দেব এবং আশা করি তিনি তাদের খুঁজে পেতে পারেন এমন পরীক্ষার সবচেয়ে মারাত্মক ধারাবাহিকতা দিয়েছেন।
animuson

1
@ এনিমুসন তার শীর্ষে, তিনি times০ বার উপচে পড়েন .... চিত্র দেখুন। আমি এখানে এসে Coz আমি সঠিক জিনিস তিনি উত্তর দেন কি করতে চান হয়নি
মূর্তিমান নিরানন্দ

ডাউনওয়োটিং যেমন প্রশ্নের উত্তর দেয় না। । চেক, আপাতদৃষ্টিতে, এই উত্তরটি লেখার জন্য প্রশ্নটি পড়েনি।
heহানেই

50
public class SwitchTest {
    public static void main(String[] args){
        for(int i = 0;i<10;i++){
            switch(i){
                case 1: case 2: case 3: case 4: //First case
                    System.out.println("First case");
                    break;
                case 8: case 9: //Second case
                    System.out.println("Second case");
                    break;
                default: //Default case
                    System.out.println("Default case");
                    break;
            }
        }
    }
}

বাইরে:

Default case
First case
First case
First case
First case
Default case
Default case
Default case
Second case
Second case

এসসিআর: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html


4
এটি তাঁর প্রশ্নের "ভার্সেস" অংশের সমান, যা তিনি এড়াতে চেয়েছিলেন।
বিডেসররর

2
কোডের উত্তরগুলি কেবলমাত্র উত্তরগুলির লিঙ্ক হিসাবে প্রায় খারাপ। এগুলি আসলেই উত্তর নয়। একটি ভাল উত্তরের ব্যাখ্যা এবং যুক্তি এবং সম্ভবত কিছু উত্স বা কর্তৃপক্ষ রয়েছে।
মার্কাস

3
এটি কোনও কিছুর চেয়ে ভাল, কিছু লোক এটিকে সেরা উত্তর হিসাবে, সহজ এবং প্রত্যক্ষ হিসাবে গ্রহণ করেন
D4rWiNS

48

পূর্ববর্তী উত্তরের মতো মার্জিত নাও হতে পারে তবে আপনি যদি কয়েকটি বড় ব্যাপ্তির সাথে স্যুইচ কেসগুলি অর্জন করতে চান তবে কেবলমাত্র একক ক্ষেত্রে রেঞ্জগুলি একত্রিত করুন:

// make a switch variable so as not to change the original value
int switchVariable = variable;

//combine range 1-100 to one single case in switch
if(1 <= variable && variable <=100)
    switchVariable = 1;
switch (switchVariable) 
{ 
    case 0:
        break; 
    case 1:
        // range 1-100
        doSomething(); 
        break;
    case 101: 
        doSomethingElse(); 
        break;
    etc.
} 

11
আমি এটি সুপারিশ করব না। আপনি যদি কেবল কোডটি চালিয়ে যান তবে আপনার স্বজ্ঞাততাটি আসবে যার case 1অর্থ variable == 1বিভ্রান্তি এবং দীর্ঘকালীন প্রচুর ব্যথা হয়। এটিকে পাঠ্যযোগ্য করে তুলতে যদি আপনার কোডটিতে মন্তব্য রাখতে হয় তবে আপনি কিছু ভুল করেছেন IMHO।
kraxor

21

অতিরিক্ত বড় switchএবং if/elseকনস্ট্রাক্টস প্রতিস্থাপনের জন্য একটি অবজেক্ট ওরিয়েন্টেড বিকল্পটি হ'ল aChain of Responsibility Patternসিদ্ধান্ত গ্রহণের মডেল হিসাবে ।

দায়িত্ব প্যাটার্নের চেইন

দায়বদ্ধতার শৃঙ্খলা অনুরোধের জন্য সম্ভাব্য বিপুল সংখ্যক হ্যান্ডলারের মধ্যে কোনটি এটির পদক্ষেপ নিতে হবে তা স্থির করে কোনও অনুরোধের উত্সকে আলাদা করার অনুমতি দেয়। চেইন রোল প্রতিনিধিত্বকারী শ্রেণি হ্যান্ডলারের তালিকার সাথে উত্স থেকে অনুরোধগুলি চ্যানেল পরিচালনা করে যতক্ষণ না কোনও হ্যান্ডলার অনুরোধ গ্রহণ না করে এবং এটি সম্পাদন করে।

জেনারিক্স ব্যবহার করে নিরাপদ টাইপ করা একটি উদাহরণ বাস্তবায়ন এখানে is

import java.util.ArrayList;
import java.util.List;

/**
* Generic enabled Object Oriented Switch/Case construct
* @param <T> type to switch on
*/
public class Switch<T extends Comparable<T>>
{
    private final List<Case<T>> cases;

    public Switch()
    {
        this.cases = new ArrayList<Case<T>>();
    }

    /**
     * Register the Cases with the Switch
     * @param c case to register
     */
    public void register(final Case<T> c) { this.cases.add(c); }

    /**
     * Run the switch logic on some input
     * @param type input to Switch on
     */
    public void evaluate(final T type)
    {
        for (final Case<T> c : this.cases)
        {
            if (c.of(type)) { break; }
        }
    }

    /**
     * Generic Case condition
     * @param <T> type to accept
     */
    public static interface Case<T extends Comparable<T>>
    {
        public boolean of(final T type);
    }

    public static abstract class AbstractCase<T extends Comparable<T>> implements Case<T>
    {
        protected final boolean breakOnCompletion;

        protected AbstractCase()
        {
            this(true);
        }

        protected AbstractCase(final boolean breakOnCompletion)
        {
            this.breakOnCompletion = breakOnCompletion;
        }
    }

    /**
     * Example of standard "equals" case condition
     * @param <T> type to accept
     */
    public static abstract class EqualsCase<T extends Comparable<T>> extends AbstractCase<T>
    {
        private final T type;

        public EqualsCase(final T type)
        {
            super();
            this.type = type;
        }

        public EqualsCase(final T type, final boolean breakOnCompletion)
        {
            super(breakOnCompletion);
            this.type = type;
        }
    }

    /**
     * Concrete example of an advanced Case conditional to match a Range of values
     * @param <T> type of input
     */
    public static abstract class InRangeCase<T extends Comparable<T>> extends AbstractCase<T>
    {
        private final static int GREATER_THAN = 1;
        private final static int EQUALS = 0;
        private final static int LESS_THAN = -1;
        protected final T start;
        protected final T end;

        public InRangeCase(final T start, final T end)
        {
            this.start = start;
            this.end = end;
        }

        public InRangeCase(final T start, final T end, final boolean breakOnCompletion)
        {
            super(breakOnCompletion);
            this.start = start;
            this.end = end;
        }

        private boolean inRange(final T type)
        {
            return (type.compareTo(this.start) == EQUALS || type.compareTo(this.start) == GREATER_THAN) &&
                    (type.compareTo(this.end) == EQUALS || type.compareTo(this.end) == LESS_THAN);
        }
    }

    /**
     * Show how to apply a Chain of Responsibility Pattern to implement a Switch/Case construct
     *
     * @param args command line arguments aren't used in this example
     */
    public static void main(final String[] args)
    {
        final Switch<Integer> integerSwitch = new Switch<Integer>();
        final Case<Integer> case1 = new EqualsCase<Integer>(1)
        {
            @Override
            public boolean of(final Integer type)
            {
                if (super.type.equals(type))
                {
                    System.out.format("Case %d, break = %s\n", type, super.breakOnCompletion);
                    return super.breakOnCompletion;
                }
                else
                {
                    return false;
                }
            }
        };
        integerSwitch.register(case1);
        // more instances for each matching pattern, granted this will get verbose with lots of options but is just
        // and example of how to do standard "switch/case" logic with this pattern.
        integerSwitch.evaluate(0);
        integerSwitch.evaluate(1);
        integerSwitch.evaluate(2);


        final Switch<Integer> inRangeCaseSwitch = new Switch<Integer>();
        final Case<Integer> rangeCase = new InRangeCase<Integer>(5, 100)
        {
            @Override
            public boolean of(final Integer type)
            {
                if (super.inRange(type))
                {
                    System.out.format("Case %s is between %s and %s, break = %s\n", type, this.start, this.end, super.breakOnCompletion);
                    return super.breakOnCompletion;
                }
                else
                {
                    return false;
                }
            }
        };
        inRangeCaseSwitch.register(rangeCase);
        // run some examples
        inRangeCaseSwitch.evaluate(0);
        inRangeCaseSwitch.evaluate(10);
        inRangeCaseSwitch.evaluate(200);

        // combining both types of Case implementations
        integerSwitch.register(rangeCase);
        integerSwitch.evaluate(1);
        integerSwitch.evaluate(10);

    }
}

এটি কেবলমাত্র একটি দ্রুত খড়ের মানুষ যা আমি কয়েক মিনিটের মধ্যে বেত্রাঘাত করেছি, আরও পরিশীলিত বাস্তবায়ন হতে Command Patternপারে একরকমের মধ্যে ইনজেকশনের অনুমতি দেয়Case প্রয়োগের ক্ষেত্রে জন্য এটি আইওসি শৈলীর আরও একটি কল ব্যাক করতে পারে।

এই পদ্ধতির সম্পর্কে একবার দুর্দান্ত জিনিসটি হ'ল স্যুইচ / কেস স্টেটমেন্টগুলি পার্শ্ব প্রতিক্রিয়া সম্পর্কে সমস্ত হয়, এটি ক্লাসগুলিতে পার্শ্ব প্রতিক্রিয়াগুলিকে আবদ্ধ করে যাতে সেগুলি পরিচালনা করতে পারে এবং আরও ভালভাবে ব্যবহার করা যায়, এটি কার্যকরী ভাষায় প্যাটার্ন ম্যাচিংয়ের মতো আরও শেষ হয় এবং এটি একটি খারাপ জিনিস নয়।

আমি গিথুব এ এই গিস্টের কোনও আপডেট বা বর্ধন পোস্ট করব ।


2
আমি সম্মত, কেস স্টেটমেন্ট এবং বড় যদি ব্লকগুলি খারাপ হয় যদি আপনার প্রচুর পরিমাণে ভেরিয়েবল থাকে। আপনি যদি কেস স্টেটমেন্টগুলি প্রচুর পরিমাণে করে থাকেন তবে আপনি ওও নীতিগুলি ব্যবহার করছেন না পাশাপাশি আপনিও হতে পারেন।
ব্লেইন মাক্লো

11

এই প্রশ্ন অনুযায়ী এটি সম্পূর্ণ সম্ভব।

একই যুক্তিযুক্ত সমস্ত কেসগুলি কেবল একসাথে রাখুন এবং breakতাদের পিছনে রাখবেন না।

switch (var) {
    case (value1):
    case (value2):
    case (value3):
        //the same logic that applies to value1, value2 and value3
        break;
    case (value4):
        //another logic
        break;
}

এটি কারণ caseছাড়া breakঅন্যটিতে ঝাঁপিয়ে পড়বে বা caseনা হওয়া পর্যন্ত ।breakreturn

সম্পাদনা করুন:

মন্তব্যের জবাব, যদি আমাদের একই যুক্তির সাথে সত্যিকারের 95 টি মান থাকে তবে বিভিন্ন যুক্তিযুক্ত একটি উপায়ে ছোট সংখ্যার ক্ষেত্রে আমরা করতে পারি:

switch (var) {
     case (96):
     case (97):
     case (98):
     case (99):
     case (100):
         //your logic, opposite to what you put in default.
         break;
     default: 
         //your logic for 1 to 95. we enter default if nothing above is met. 
         break;
}

আপনি যদি সূক্ষ্ম নিয়ন্ত্রণ প্রয়োজন, if-elseপছন্দ হয়।


2
প্রশ্নটি ইতিমধ্যে এটি একটি সমাধান হিসাবে সরবরাহ করে এবং জিজ্ঞাসা করে যে সীমার প্রতিটি মান কোড না করেই কোনও পরিসীমা নির্দিষ্ট করার কোনও উপায় রয়েছে (ওপিতে casestatements৯ টি বিবৃতি প্রয়োজন !) আমি আশঙ্কা করছি আমি গৃহীত উত্তরের সাথে একমত হই।
বোহেমিয়ান

মন্তব্যের জন্য ধন্যবাদ। সম্পাদনা দেখুন, হতে পারে। আমি সম্মত হই যে এটি সমস্ত দৃশ্যের উপর নির্ভর করে এবং 5 বনাম 95 এর ক্ষেত্রে নাও হতে পারে।
ওয়েস্টার্নগুন

6

মূলত:

if (variable >= 5 && variable <= 100)
{
    doSomething();
}

আপনার যদি সত্যিই কোনও স্যুইচ ব্যবহারের প্রয়োজন হয় তবে এটি এমন হবে কারণ নির্দিষ্ট রেঞ্জের জন্য আপনার বিভিন্ন জিনিস করা দরকার। সেক্ষেত্রে হ্যাঁ, আপনার কাছে অগোছালো কোড থাকবে, কারণ জিনিসগুলি জটিল হয়ে উঠছে এবং কেবল নিদর্শনগুলি অনুসরণ করে এমন জিনিসগুলি ভালভাবে সংকোচিত হতে চলেছে।

যদি আপনি কেবল সংখ্যার স্যুইচিং মানগুলির পরীক্ষা করে থাকেন তবে স্যুইচটির একমাত্র কারণ পরিবর্তনশীল নামটি টাইপ করা বাঁচানো। আপনি 100 টি জিনিস স্যুইচ করতে যাচ্ছেন না, এবং তারা সব একই জিনিস করছেন না। এটি আরও বেশি 'ইফ' অংশের মতো শোনাচ্ছে।


4

// অবিরাম কোড উদাহরণ

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();

  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

// কমপ্লায়েন্ট সলিউশন

switch (i) {
  case 1:
  case 3:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  default:
    doTheRest();
}

if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else {
  doTheRest();
}

সত্যিকারের উত্তর যা থাম্বস অবধি প্রাপ্য। খুশী হলাম।
ব্যবহারকারী 1735921

1
আপনাকে ধন্যবাদ ব্যবহারকারী 1735921
মনোজ কুমার শর্মা

3

শেষ জাভা -১২ রিলিজ থেকে একই কেস লেবেলে একাধিক ধ্রুবক পূর্বরূপ ভাষা বৈশিষ্ট্যে উপলভ্য

এটি বাস্তব জগত ব্যবহারের ভিত্তিতে বিকাশকারীদের প্রতিক্রিয়া প্ররোচিত করার জন্য একটি জেডিকে বৈশিষ্ট্য রিলিজে পাওয়া যায়; এটি ভবিষ্যতে জাভা এসই প্ল্যাটফর্মে স্থায়ী হয়ে যেতে পারে।

এটা দেখতে অনেকটা:

switch(variable) {
    case 1 -> doSomething();
    case 2, 3, 4 -> doSomethingElse();
};

আরও জেপি 325 দেখুন: স্যুইচ এক্সপ্রেশন (পূর্বরূপ)


2

এটি Vavr লাইব্রেরি ব্যবহার করে পরিচালনা করা সম্ভব

import static io.vavr.API.*;
import static io.vavr.Predicates.*;

Match(variable).of(
    Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
    Case($(), () -> handleCatchAllCase())
);

এটি অবশ্যই কেবলমাত্র সামান্য উন্নতি হিসাবে সমস্ত মামলা এখনও স্পষ্টভাবে তালিকাভুক্ত করা প্রয়োজন। তবে কাস্টম প্রিডিকেট সংজ্ঞায়িত করা সহজ:

public static <T extends Comparable<T>> Predicate<T> isInRange(T lower, T upper) {
    return x -> x.compareTo(lower) >= 0 && x.compareTo(upper) <= 0;
}

Match(variable).of(
    Case($(isInRange(5, 100)), () -> doSomething()),
    Case($(), () -> handleCatchAllCase())
);

ম্যাচ একটি অভিব্যক্তি তাই এখানে এটি Runnableসরাসরি পদ্ধতিতে ডাকার পরিবর্তে উদাহরণের মতো কিছু দেয় । ম্যাচ সম্পাদনের পরে Runnableমৃত্যুদন্ড কার্যকর করা যেতে পারে।

আরও তথ্যের জন্য দয়া করে অফিসিয়াল ডকুমেন্টেশন দেখুন


1

বিকল্পের জন্য আপনি নীচের হিসাবে ব্যবহার করতে পারেন:

if (variable >= 5 && variable <= 100) {
        doSomething();

    }

অথবা নিম্নলিখিত কোডটিও কাজ করে

switch (variable)
{
    case 5:
    case 6:
    etc.
    case 100:
        doSomething();
    break;
}

1

জেপি 354: জেডিকে -13 এবং জেপি 361 -এ স্যুইচ এক্সপ্রেশন (পূর্বরূপ) : জেডিকে -১ 14 এ স্যুইচ এক্সপ্রেশন (স্ট্যান্ডার্ড) সুইচ স্টেটমেন্টটি প্রসারিত করবেযাতে এটি একটি এক্সপ্রেশন হিসাবে ব্যবহার করা যায়

এখন তুমি পার:

  • সুইচ এক্সপ্রেশন থেকে সরাসরি পরিবর্তনশীল বরাদ্দ করুন ,
  • স্যুইচ লেবেলের নতুন ফর্ম ব্যবহার করুন (case L -> ):

    "কেস এল ->" স্যুইচ লেবেলের ডানদিকে কোডটি এক্সপ্রেশন, ব্লক বা (সুবিধার জন্য) একটি থ্রো স্টেটমেন্ট হিসাবে সীমাবদ্ধ।

  • প্রতি কেস প্রতি একাধিক স্থায়ী ব্যবহার করুন, কমা দ্বারা পৃথক করা,
  • এবং আরও কোন মান বিরতি আছে :

    একটি স্যুইচ এক্সপ্রেশন থেকে একটি মান উপার্জন করতে, breakমান বিবৃতি সহ একটি yieldস্টেটমেন্টের পক্ষে বাদ দেওয়া হয় ।

অভিব্যক্তি উদাহরণ পরিবর্তন করুন:

public class SwitchExpression {

  public static void main(String[] args) {
      int month = 9;
      int year = 2018;
      int numDays = switch (month) {
        case 1, 3, 5, 7, 8, 10, 12 -> 31;
        case 4, 6, 9, 11 -> 30;
        case 2 -> {
          if (java.time.Year.of(year).isLeap()) {
            System.out.println("Wow! It's leap year!");
            yield 29;
          } else {
            yield 28;
          }
        }
        default -> {
          System.out.println("Invalid month.");
          yield 0;
        }
      };
      System.out.println("Number of Days = " + numDays);
  }
}

0

হার্ড-কোডড মানগুলি ব্যবহার না করার পরিবর্তে একটি বিকল্প পরিবর্তে স্যুইচ স্টেটমেন্টে রেঞ্জ ম্যাপিংগুলি ব্যবহার করতে পারে:

private static final int RANGE_5_100 = 1;
private static final int RANGE_101_1000 = 2;
private static final int RANGE_1001_10000 = 3;

public boolean handleRanges(int n) {
    int rangeCode = getRangeCode(n);
    switch (rangeCode) {
        case RANGE_5_100: // doSomething();
        case RANGE_101_1000: // doSomething();
        case RANGE_1001_10000: // doSomething();
        default: // invalid range
    }
}

private int getRangeCode(int n) {
    if (n >= 5 && n <= 100) {
        return RANGE_5_100;
    } else if (n >= 101 && n <= 1000) {
        return RANGE_101_1000;
    } else if (n >= 1001 && n <= 10000) {
        return RANGE_1001_10000;
    }

    return -1;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.