Fun*_*ode 108 java syntax switch-statement
只是想弄清楚如何在Java switch语句中使用多个案例.这是我正在尝试做的一个例子:
switch (variable)
{
case 5..100:
doSomething();
break;
}
Run Code Online (Sandbox Code Playgroud)
与必须做的:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
Run Code Online (Sandbox Code Playgroud)
任何想法,如果这可能,或什么是一个好的选择?
Bal*_*a R 78
可悲的是,这在Java中是不可能的.你将不得不求助于使用if-else陈述.
小智 77
第二种选择完全没问题.我不确定为什么响应者说不可能.这很好,我一直这样做:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
Run Code Online (Sandbox Code Playgroud)
小智 47
也许不像之前的一些答案那样优雅,但是如果你想要实现几个大范围的开关盒,只需事先将范围组合到一个案例中:
// 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.
}
Run Code Online (Sandbox Code Playgroud)
P. *_*man 45
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
日期:
Default case
First case
First case
First case
First case
Default case
Default case
Default case
Second case
Second case
Run Code Online (Sandbox Code Playgroud)
Src:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Ris*_*shi 22
这可以通过Java 14中的 switch 增强功能实现。以下是一个相当直观的示例,说明如何实现相同的目标。
switch (month) {
case 1, 3, 5, 7, 8, 10, 12 -> System.out.println("this month has 31 days");
case 4, 6, 9 -> System.out.println("this month has 30 days");
case 2 -> System.out.println("February can have 28 or 29 days");
default -> System.out.println("invalid month");
}
Run Code Online (Sandbox Code Playgroud)
小智 20
替换过大switch和if/else构造的一个面向对象的选项是使用a Chain of Responsibility Pattern来模拟决策.
责任链模式
责任链模式允许将请求源分离,以决定请求中哪些潜在的大量处理程序应该对其执行操作.表示链角色的类沿着处理程序列表传递来自源的请求,直到处理程序接受请求并对其进行操作.
这是一个使用泛型的类型安全的示例实现.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这只是一个快速的稻草人,我在几分钟内掀起,一个更复杂的实现可能允许某种类型Command Pattern被注入到Case实现实例中,使其更像是回调IoC风格.
关于这种方法的一个好处是Switch/Case语句都是关于副作用的,它将副作用封装在Classes中,这样它们可以被管理,并且可以更好地重复使用,最终更像是函数式语言中的模式匹配,这不是一件坏事.
我将在Github上发布此Gist的任何更新或增强功能.
JEP 354: JDK-13 中的Switch 表达式(预览)和JEP 361: JDK-14 中的 Switch 表达式(标准)将扩展switch 语句,以便它可以用作表达式。
现在你可以:
case L ->):
“case L ->”开关标签右侧的代码仅限于表达式、块或(为方便起见)抛出语句。
为了从 switch 表达式中产生一个值,
breakwith value 语句被删除,取而代之的是一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
基本上:
if (variable >= 5 && variable <= 100)
{
doSomething();
}
Run Code Online (Sandbox Code Playgroud)
如果你真的需要使用开关,那将是因为你需要为某些范围做各种事情.在这种情况下,是的,你将会遇到混乱的代码,因为事情变得越来越复杂,只有遵循模式的东西才能很好地压缩.
切换的唯一原因是,如果您只是测试数字切换值,则可以节省输入变量名称.你不会打开100件事,他们也不会做同样的事情.这听起来更像是'if'块.
根据这个问题,完全有可能。
只需将所有包含相同逻辑的案例放在一起,不要将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;
}
Run Code Online (Sandbox Code Playgroud)
这是因为,case如果没有,break它将跳到另一个,case直到break或return。
编辑:
回复评论,如果我们确实有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;
}
Run Code Online (Sandbox Code Playgroud)
如果需要更好的控制,if-else则是选择。
从最新的 java-12 版本开始,预览语言功能中可以使用同一 case 标签中的多个常量
它在 JDK 功能版本中可用,以激发开发人员根据实际使用情况提供反馈;这可能会导致它在未来的 Java SE 平台中永久存在。
看起来像:
switch(variable) {
case 1 -> doSomething();
case 2, 3, 4 -> doSomethingElse();
};
Run Code Online (Sandbox Code Playgroud)