programing

Java 스위치 문의 여러 케이스

procenter 2022. 9. 18. 21:12
반응형

Java 스위치 문의 여러 케이스

자바 스위치 문에 여러 케이스를 사용하는 방법을 알아보려고 합니다.다음은 제가 하려는 일의 예입니다.

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

다음과 같은 작업을 수행해야 합니다.

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

가능하다면 어떤 아이디어나 좋은 대안이 있을까요?

두 번째 옵션은 완전히 괜찮습니다.나는 왜 응답자가 그것이 불가능하다고 말했는지 모르겠다.이건 괜찮아, 난 항상 이걸 하고 있어.

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

이치노 하다, , 하다, 하다, 하다, 하다를 해야 합니다if-else★★★★★★★★★★★★★★★★★★.

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

Src: 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는 constructions를 입니다.Chain of Responsibility Pattern모델을 만들 수 있습니다.

책임 사슬의 패턴

책임 체인의 패턴을 사용하면, 요구의 송신원을, 그 요구에 대응하는 대량의 핸들러 중 어느 것을 처리할지를 결정하는 것으로부터 분리할 수 있습니다.체인 역할을 나타내는 클래스는 핸들러가 요청을 받아들여 액션을 수행할 때까지 핸들러 목록을 따라 소스로부터의 요청을 채널링합니다.

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

    }
}

좀 더 정교한 의 빨대맨을 할 수 있을지도 모릅니다.Command Pattern Case구현 인스턴스를 사용하여 콜백 IOC 스타일로 만듭니다.

이 어프로치의 장점은 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 데로 뛰어오르다casebreak ★★★★★★★★★★★★★★★★★」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택입니니다다

이는 Java 14의 스위치 확장을 통해 가능합니다.다음은 동일한 작업을 수행하는 방법에 대한 매우 직관적인 예입니다.

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

기본적으로:

if (variable >= 5 && variable <= 100)
{
    doSomething();
}

스위치를 사용할 필요가 있는 경우는, 특정의 범위에서 다양한 작업을 실시할 필요가 있기 때문입니다.이 경우 코드가 복잡해지고 패턴을 따르는 것만이 잘 압축되기 때문입니다.

숫자 스위칭 값만 테스트하는 경우 변수 이름을 입력하는 데 드는 비용을 절약하기 위해서만 스위치를 사용할 수치의 스위칭 값만 테스트하면 됩니다.여러분은 100개의 스위치를 켜지 않을 것이고, 그것들은 모두 같은 일을 하지 않을 것입니다.그건 '만약' 청크에 가깝네요.

이전 Java-12 릴리즈부터 동일한 케이스의 여러 상수를 미리보기 언어 기능으로 사용할 수 있습니다.

JDK 기능 릴리스에서는 실제 사용에 기초한 개발자 피드백을 유도하기 위해 사용할 수 있습니다.이것에 의해, 장래의 Java SE Platform에서는 영속적인 것이 될 가능성이 있습니다.

외관:

switch(variable) {
    case 1 -> doSomething();
    case 2, 3, 4 -> doSomethingElse();
};

기타 JEP 325: 스위치식(미리보기) 보기

JDK-13의 스위치 식(미리보기)및 JDK-14의 JEP 361: 스위치 식(표준)으로서 사용할 수 있도록 스위치 을 확장합니다.

이것으로, 이하를 실현할 수 있습니다.

  • 스위치 식에서 직접 변수를 할당합니다.
  • 을 사용합니다(「」).case L ->):

    "case L ->" 스위치라벨 오른쪽에 있는 코드는 식, 블록 또는 (편리상) throw 문으로 제한됩니다.

  • 콤마로 구분된 여러 개의 상수를 사용합니다.
  • 또, 가치의 저하도 없습니다.

    식에서 하려면 , 「」를 해 주세요.break 스테이트먼트가 있는 는, 「 statement」의 값을 됩니다.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);
  }
}

// 비준수 코드 예시

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

Vavr 라이브러리를 사용하여 이 문제를 처리할 수 있습니다.

import static io.vavr.API.*;
import static io.vavr.Predicates.*;

Match(variable).of(
    Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
    Case($(), () -> handleCatchAllCase())
);

모든 사례를 명시적으로 나열해야 하므로 이는 물론 약간의 개선 사항일 뿐입니다.그러나 커스텀 술어는 쉽게 정의할 수 있습니다.

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

매치는 표현이기 때문에 여기서 다음과 같은 것을 반환한다.Runnable메서드를 직접 호출하는 대신 인스턴스를 호출합니다.일치 실행 후Runnable실행할 수 있습니다.

상세한 것에 대하여는, 공문서를 참조해 주세요.

하드 코드화된 값을 사용하는 대신 스위치스테이트먼트 상에서 범위 매핑을 사용하는 방법도 있습니다.

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

다른 방법으로 다음과 같이 사용할 수 있습니다.

if (variable >= 5 && variable <= 100) {
        doSomething();

    }

또는 다음 코드도 작동합니다.

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

나는 이 문제에 대한 해결책을 찾았다.자바에서는 스위치 케이스에서 여러 조건을 사용할 수 있습니다.단, 여러 스위치 케이스가 필요합니다.

public class MultiCSwitchTest {
public static void main(String[] args) {
    int i = 209;
    int a = 0;
    switch (a = (i>=1 && i<=100) ? 1 : a){    
    case 1:
        System.out.println ("The Number is Between 1 to 100 ==> " + i);
        break;
    default:
        switch (a = (i>100 && i<=200) ? 2 : a) {
            case 2:
                System.out.println("This Number is Between 101 to 200 ==> " + i);
                break;
        
            default:
                switch (a = (i>200 && i<=300) ? 3 : a) {
                    case 3:
                        System.out.println("This Number is Between 201 to 300 ==> " + i);
                        break;
                
                    default:
                        // You can make as many conditions as you want;
                        break;
                }
        }
        
    }
}
}

언급URL : https://stackoverflow.com/questions/5086322/java-switch-statement-multiple-cases

반응형