Java switch 문 여러 경우
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;
}
이전 답변만큼 우아하지는 않지만 큰 범위가 거의없는 스위치 케이스를 얻으려면 미리 범위를 단일 케이스로 결합하십시오.
// 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.
}
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
옵션을 지향 한 개체 과도하게 큰 교체 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에 게시하겠습니다 .
원래:
if (variable >= 5 && variable <= 100)
{
doSomething();
}
정말 스위치를 사용해야한다면 특정 범위에 대해 다양한 작업을해야하기 때문일 것입니다. 이 경우, 예, 당신은 복잡한 코드를 갖게 될 것입니다. 왜냐하면 상황이 복잡해지고 패턴을 따르는 것만 잘 압축 될 것이기 때문입니다.
전환의 유일한 이유는 숫자 전환 값을 테스트하는 경우 변수 이름 입력을 절약하기위한 것입니다. 당신은 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;
}
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
선택합니다.
// 비준수 코드 예제
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();
}
It is possible to handle this using Vavr library
import static io.vavr.API.*;
import static io.vavr.Predicates.*;
Match(variable).of(
Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
Case($(), () -> handleCatchAllCase())
);
This is of course only slight improvement since all cases still need to be listed explicitly. But it is easy to define custom predicate:
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 is an expression so here it returns something like Runnable
instance instead of invoking methods directly. After match is performed Runnable
can be executed.
For further details please see official documentation.
for alternative you can use as below:
if (variable >= 5 && variable <= 100) {
doSomething();
}
or the following code also works
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
From the last java-12 release multiple constants in the same case label is available in preview language feature
It is available in a JDK feature release to provoke developer feedback based on real world use; this may lead to it becoming permanent in a future Java SE Platform.
It looks like:
switch(variable) {
case 1 -> doSomething();
case 2, 3, 4 -> doSomethingElse();
};
See more JEP 325: Switch Expressions (Preview)
One alternative instead of using hard-coded values could be using range mappings on the the switch statement instead:
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;
}
참고URL : https://stackoverflow.com/questions/5086322/java-switch-statement-multiple-cases
'programing' 카테고리의 다른 글
Nodejs-리디렉션 URL (0) | 2020.08.14 |
---|---|
" 'Microsoft.ACE.OLEDB.12.0'공급자가 로컬 컴퓨터에 등록되지 않았습니다."xlsx 프로세스를 SQL 서버로 가져 오는 동안 오류 발생 (0) | 2020.08.14 |
ActiveRecord : 콘솔에서 테이블의 열 나열 (0) | 2020.08.14 |
자바 스크립트 및 정규식 : 문자열을 분할하고 구분 기호 유지 (0) | 2020.08.14 |
Angular CLI 오류 : serve 명령을 Angular 프로젝트에서 실행해야하지만 프로젝트 정의를 찾을 수 없습니다. (0) | 2020.08.14 |