Java switch 문에 여러 사례를 사용하는 방법을 알아 내려고합니다. 다음은 내가하려는 작업의 예입니다.
switch (variable)
{
case 5..100:
doSomething();
break;
}
해야 할 일과 비교 :
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
이것이 가능하다면 어떤 아이디어 나 좋은 대안은 무엇입니까?
답변
슬프게도 Java에서는 불가능합니다. if-else
문 사용에 의지해야 합니다.
답변
두 번째 옵션은 완전히 괜찮습니다. 응답자가 왜 불가능하다고 말했는지 모르겠습니다. 이것은 괜찮습니다. 저는 항상 이것을합니다.
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;
}
}
}
}
밖:
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
답변
이전 답변만큼 우아하지는 않지만 큰 범위가 거의없는 스위치 케이스를 얻으려면 미리 범위를 단일 케이스로 결합하십시오.
// 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.
}
답변
옵션을 지향 한 개체 과도하게 큰 교체 switch
및 if/else
구조는을 사용하는 Chain of Responsibility Pattern
의사 결정을 모델링 할 수 있습니다.
책임의 사슬 패턴
책임 체인 패턴을 사용하면 요청에 대해 잠재적으로 많은 수의 핸들러 중 어느 것이 조치를 취해야하는지 결정하는 것으로부터 요청 소스를 분리 할 수 있습니다. 체인 역할을 나타내는 클래스는 핸들러가 요청을 수락하고 조치를 취할 때까지 핸들러 목록을 따라 소스의 요청을 채널링합니다.
다음은 Generics를 사용하는 Type Safe 인 구현의 예입니다.
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);
}
}
이것은 내가 몇 분 만에 채찍질 한 빠른 짚 맨일 뿐이다. 좀 더 정교한 구현은 콜백 IoC 스타일로 만들기 위해 구현 인스턴스 에 어떤 종류의 Command Pattern
주입을 허용 할 수 있다 Case
.
이 접근 방식에 대한 좋은 점은 Switch / Case 문이 모두 부수적 영향에 관한 것이라는 점입니다. 이것은 부수 효과를 클래스에 캡슐화하여 관리하고 더 잘 재사용 할 수 있도록합니다. 결국 기능적 언어의 패턴 일치와 비슷해집니다. 그것은 나쁜 것이 아닙니다.
이 Gist 에 대한 업데이트 나 개선 사항을 Github에 게시하겠습니다 .
답변
이 질문 에 따르면 전적으로 가능합니다.
동일한 논리를 포함하는 모든 케이스를 함께 배치하고 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
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;
}
더 세밀한 제어가 필요한 경우 if-else
선택합니다.
답변
원래:
if (variable >= 5 && variable <= 100)
{
doSomething();
}
정말 스위치를 사용해야한다면 특정 범위에 대해 다양한 작업을해야하기 때문일 것입니다. 이 경우, 예, 당신은 복잡한 코드를 갖게 될 것입니다. 왜냐하면 상황이 복잡해지고 패턴을 따르는 것만 잘 압축 될 것이기 때문입니다.
전환의 유일한 이유는 숫자 전환 값을 테스트하는 경우 변수 이름 입력을 절약하기위한 것입니다. 당신은 100 가지를 켜지 않을 것이고, 그들은 모두 같은 일을하지 않을 것입니다. 그것은 ‘if’청크처럼 들립니다.