155 votes

Instruction de commutation Java plusieurs cas

J'essaie juste de comprendre comment utiliser plusieurs cas multiples pour une instruction java switch. Voici un exemple de ce que j'essaie de faire:

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

versus devoir faire:

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

Des idées si cela est possible, ou quelle bonne alternative est?

107voto

Dave Points 311

La deuxième option est tout à fait correcte. Je ne sais pas pourquoi un intervenant a dit que ce n'était pas possible. C'est bien et je le fais tout le temps:

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

91voto

Bala R Points 57552

Malheureusement, ce n'est pas possible en Java. Vous devrez recourir aux déclarations if-else .

67voto

Sworn Points 109
 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;
            }
        }
    }
}
 

En dehors:

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

Src: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

51voto

Santtu Kähkönen Points 209

Peut-être pas aussi élégant que certaines réponses précédentes, mais si vous voulez réaliser des cas de commutation avec peu de plages étendues, combinez simplement des plages à un cas unique auparavant:

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

//combine range 1-99 to 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.
} 
 

23voto

Jarrod Roberson Points 32263

L'une Orientée Objet option pour remplacer trop grand switch et if/else des constructions est d'utiliser un Chain of Responsibility Pattern le modèle de la prise de décision.

Modèle chaîne de Responsabilité

Le modèle chaîne de responsabilité permet la séparation de la source de une demande de décider qui de la potentiellement un grand nombre de gestionnaires d' de la demande devraient action. L' classe représentant la chaîne de rôle les canaux de la demande à partir de la source le long de la liste des maîtres-chiens jusqu'à ce qu'un gestionnaire accepte la demande et actions.

Voici un exemple de mise en œuvre qui est également de Type Coffre-fort à l'aide de médicaments Génériques.

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);

    }
}

C'est un simple homme de paille que je fouettée, en quelques minutes, une version plus sophistiquée de la mise en œuvre pourrait permettre une sorte de Command Pattern à être injecté dans l' Case des implémentations cas pour la rendre plus d'un appel de retour Cio style.

Une fois la bonne chose à propos de cette approche est que le Commutateur de Cas, les états sont tous sur les effets secondaires, cela résume les effets secondaires dans les Classes de sorte qu'ils peuvent être gérés, et ré-utilisés mieux, il finit par n'être plus comme le Modèle Correspondant dans un langage Fonctionnel et qui n'est pas une mauvaise chose.

Je vais poster des mises à jour ou des améliorations de ce Gist sur Github.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X