poner - textarea java netbeans
Sentencia de conmutación múltiple de Java (10)
// Ejemplo de código no conforme
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();
}
// Solución compatible
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();
}
Solo intento descubrir cómo usar muchos casos múltiples para una declaración de cambio de Java. Aquí hay un ejemplo de lo que estoy tratando de hacer:
switch (variable)
{
case 5..100:
doSomething();
break;
}
versus tener que hacer:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
¿Alguna idea si esto es posible, o qué buena alternativa es?
Básicamente:
if (variable >= 5 && variable <= 100)
{
doSomething();
}
Si realmente necesita usar un interruptor, sería porque necesita hacer varias cosas para ciertos rangos. En ese caso, sí, vas a tener un código desordenado, porque las cosas se están volviendo complejas y solo las cosas que siguen los patrones se van a comprimir bien.
La única razón para un cambio es guardar al escribir el nombre de la variable si solo está probando valores de conmutación numéricos. No va a activar 100 cosas, y no todas van a hacer lo mismo. Eso suena más como un trozo ''si''.
Es posible manejar esto usando la biblioteca Vavr
import static io.vavr.API.*;
import static io.vavr.Predicates.*;
Match(variable).of(
Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
Case($(), () -> handleCatchAllCase())
);
Por supuesto, esto es solo una ligera mejora, ya que todos los casos aún deben enumerarse explícitamente. Pero es fácil definir un predicado personalizado:
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())
);
Match es una expresión, por lo que aquí devuelve algo así como la instancia de Runnable
lugar de invocar métodos directamente. Una vez realizada la Runnable
, Runnable
puede ejecutarse.
Para más detalles, consulte la documentación oficial .
La segunda opción está completamente bien. No estoy seguro de por qué un respondedor dijo que no era posible. Esto está bien, y lo hago todo el tiempo:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
Lamentablemente, no es posible en Java. Tendrás que recurrir al uso if-else
sentencias if-else
.
Según esta pregunta , es totalmente posible.
Simplemente coloque todos los casos que contengan la misma lógica juntos, y no los deje atrás.
switch (var) {
case (value1):
case (value2):
case (value3):
//the same logic that applies to value1, value2 and value3
break;
case (value4):
//another logic
break;
}
Es porque el case
sin break
saltará a otro case
hasta la break
o el return
.
EDITAR:
Respondiendo al comentario, si realmente tenemos 95 valores con la misma lógica, pero mucho menos casos con lógica diferente, podemos hacer:
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;
}
Si necesita un control más fino, if-else
es la elección.
Tal vez no sea tan elegante como algunas respuestas anteriores, pero si desea lograr cajas de conmutadores con pocos rangos grandes, simplemente combine rangos para un solo caso de antemano:
// 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.
}
Una opción orientada a objetos para reemplazar los switch
excesivamente grandes y las construcciones if/else
es utilizar un Chain of Responsibility Pattern
para modelar la toma de decisiones.
Patrón de cadena de responsabilidad
El patrón de cadena de responsabilidad permite que la separación de la fuente de una solicitud pueda decidir cuál de los posibles controladores de la solicitud debe actuar. La clase que representa la función de cadena canaliza las solicitudes desde la fuente a lo largo de la lista de manejadores hasta que un manejador acepta la solicitud y la ejecuta.
Aquí hay una implementación de ejemplo que también es Type Safe usando Generics.
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);
}
}
Este es solo un truco rápido que elevé en pocos minutos, una implementación más sofisticada podría permitir que se inserte algún tipo de Command Pattern
de Command Pattern
en las instancias de las implementaciones de Case
para que sea más un estilo de IoC de devolución de llamada.
Una vez, lo bueno de este enfoque es que las instrucciones Switch / Case tienen que ver con los efectos secundarios, esto encapsula los efectos secundarios en las clases para que puedan ser administrados y reutilizados mejor, termina siendo más parecido a la coincidencia de patrones en un lenguaje funcional y eso no es algo malo
Publicaré cualquier actualización o mejora de este Gist en Github.
para una alternativa que puede usar de la siguiente manera:
if (variable >= 5 && variable <= 100) {
doSomething();
}
o el siguiente código también funciona
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
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;
}
}
}
}
Fuera:
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