Вопрос по switch-statement, if-statement, java – В Java, используя оператор switch с диапазоном значений в каждом случае?

84

В Java можно написать оператор переключения, где каждый случай содержит более одного значения? Например (хотя ясно, что следующий код не будет работать):

switch (num) {
    case 1 .. 5:
        System.out.println("testing case 1 to 5");
        break;
    case 6 .. 10:
        System.out.println("testing case 6 to 10");
        break;
}

Я думаю, что это можно сделать в Objective C, есть ли подобное в Java? Или я должен просто использоватьif, else if заявления вместо?

Есть даже расширения в простом C, которые позволяют это. arshajii

Ваш Ответ

14   ответов
3

case заявление с использованием механизмаfall through разрешено оператором switch, это упомянуто вУчебник по Java и полностью указано в разделе& # XA7; 14.11. Заявление коммутатора изСпецификация языка Java.

Следующий фрагмент кода был взят из примера в учебном пособии, он вычисляет количество дней в каждом месяце (пронумерованных от месяца 1 до месяца 12):

switch (month) {
    case 1: case 3: case 5:
    case 7: case 8: case 10:
    case 12:
        numDays = 31;
        break;
    case 4: case 6:
    case 9: case 11:
        numDays = 30;
        break;
    case 2:
        if (((year % 4 == 0) && 
             !(year % 100 == 0))
             || (year % 400 == 0))
            numDays = 29;
        else
            numDays = 28;
        break;
    default:
        System.out.println("Invalid month.");
        break;
}

Как видите, для охвата диапазона значений в одномcase Заявление Единственная альтернатива состоит в том, чтобы перечислить каждое из возможных значений по отдельности, одно за другим. В качестве дополнительного примера, вот как реализовать псевдокод в вопросе:

switch(num) {
    case 1: case 2: case 3: case 4: case 5:
        System.out.println("testing case 1 to 5");
        break;
    case 6: case 7: case 8: case 9: case 10:
        System.out.println("testing case 6 to 10");
        break;
}
1

Код более многословен (по крайней мере, для непрерывных интервалов), чем это может быть, и требует перегрузок / приведений и / или параметризации для long, float, Integer и т. Д.

if (num < 1)
    System.Out.Println("invalid case: " + num); // you should verify that anyway
else if (num <= 5)
    System.Out.Println("1 to 5");
else if (num <= 10)
    System.Out.Println("6 to 10");
else if (num <= 42)
    System.Out.Println("11 to 42");
else    
    System.Out.Println("43 to +infinity");
@missingfaktor1. Я полагаю, это дело вкуса. Когда я имею дело с непрерывными интервалами, мне лично нравится думать оifкак будто я постепенно выливаюсь из нижнего поддиапазона. Кроме того, избыточное вычисление не является проблемой вообще, но избыточное сравнение немного беспокоит: становится проще выполнять смежные сравнения несинхронно, например. после некоторого редактирования:if (isBetween(x, 1, 4)) {...} else if (isBetween(x, 6, 10)), Во всяком случае, ничего страшного.
Что касается необходимости перегрузок и приведений, это не является действительной критикой IMO. То, что в Java нет разумного способа абстрагирования над числовыми типами, говорит об ограничениях Java больше, чем об этом подходе. Возможно, вы захотите изучить язык HaskellNum type-class, если вы хотите лучше понять этот момент.
2. Согласовано - ограничение Java, но это то, с чем мы должны работать, и ваш исходный код будет продублирован для различных типов. В этом конкретном случае проблему можно решить, используяNumber класс, хотя подход Haskell лучше (никогда не приходилось по-настоящему изучать Haskell, но он напоминает "Concepts Light" C ++. Также, я полагаю, вы имели в видуRealнеNum).
Извините за поздний ответ, я не могу идти в ногу с SO ответами в последнее время. Я отвечу на вашу критику один за другим. 1. Код немного более многословен, да, и он также выполняет некоторые избыточные вычисления. Но это IMO помогает ясности в этом случае. В вашем коде нужно помнить предыдущие случаи, когда кто-то падает по лестнице.
2

enum представлять ваши диапазоны,

public static enum IntRange {
  ONE_TO_FIVE, SIX_TO_TEN;
  public boolean isInRange(int v) {
    switch (this) {
    case ONE_TO_FIVE:
      return (v >= 1 && v <= 5);
    case SIX_TO_TEN:
      return (v >= 6 && v <= 10);
    }
    return false;
  }

  public static IntRange getValue(int v) {
    if (v >= 1 && v <= 5) {
      return ONE_TO_FIVE;
    } else if (v >= 6 && v <= 10) {
      return SIX_TO_TEN;
    }
    return null;
  }
}
2

NavigableMap реализация, какTreeMap.

/* Setup */
NavigableMap<Integer, Optional<String>> messages = new TreeMap<>();
messages.put(Integer.MIN_VALUE, Optional.empty());
messages.put(1, Optional.of("testing case 1 to 5"));
messages.put(6, Optional.of("testing case 6 to 10"));
messages.put(11, Optional.empty());

/* Use */
messages.floorEntry(3).getValue().ifPresent(System.out::println);
@ChVas способ, которым карта настроена здесь,floorEntry() никогда не вернетсяnull (вставляяInteger.MIN_VALUE ключ предназначен для предотвращения этого). Но, независимо от вашего типа значения, вам нужно решить, как обрабатывать ключи за пределами допустимого диапазона.
Отличное решение! не забудьте проверить на нулевое значение, используяif (messages.floorEntry(value)!=null)  если вы используете целочисленное значение
4

case 1:
case 2:
case 3:
case 4:
case 5: 
  System.Out.Println("testing case 1 to 5");
break;
73

switch заявления

switch (num) {
case 1:
case 2:
case 3:
case 4:
case 5:
     System.out.println("1 through 5");
     break;
case 6:
case 7:
case 8:
case 9:
case 10:
     System.out.println("6 through 10");
     break;
}

использованиеif заявления.

91

public static boolean isBetween(int x, int lower, int upper) {
  return lower <= x && x <= upper;
}

if (isBetween(num, 1, 5)) {
  System.out.println("testing case 1 to 5");
} else if (isBetween(num, 6, 10)) {
  System.out.println("testing case 6 to 10");
}
Это прекрасно работает и просто. Также, если вы хотите выбрать числа, не входящие в диапазон, все, что вам нужно, это если (! IsBetween ..., хорошая работа.
@missingfaktor I 'vecriticized Ваш ответ немного. Итак, вы, вероятно, захотите что-то ответить. +1 хотя.
@missingfaktor Извините. Но это изменение было одобрено давно; Я даже не помню, что когда-либо делал это.
@MCEmperor, пожалуйста, не редактируйте мой ответ с вашими личными предпочтениями форматирования. Это бесполезное редактирование.
4

public static int range(int num){ 
    if ( 10 < num && num < 20)
        return 1;
    if ( 20 <= num && num < 30)
        return 2;
    return 3;
}

public static final int TEN_TWENTY = 1;
public static final int TWENTY_THIRTY = 2;

public static void main(String[]args){
    int a = 110;
    switch (range(a)){
        case TEN_TWENTY: 
            System.out.println("10-20"); 
            break;
        case TWENTY_THIRTY: 
            System.out.println("20-30"); 
            break;
        default: break;
    }
}
Диапазон функции возвращает некоторое значение в соответствии с входным аргументом, поэтому «диапазон значений» Обнаружение может быть сделано здесь, в сочетании с предложением о переключателе.
не могли бы вы дать объяснение тоже ..?
Это работает для моего варианта использования, у меня есть 2 переменная int, и я хочу проверить, что 2 переменные находятся в том же диапазоне, как (10-20), (20-30), .... как это
4

что этот пост старый, но я считаю, что этот ответ заслуживает некоторого признания. Нет необходимости избегать оператора switch. Это можно сделать в Java, но с помощью оператора switch, а не в случаях. Это предполагает использование троичных операторов.

public class Solution {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());

        switch ((1 <= num && num <= 5 ) ? 0 :
                (6 <= num && num <= 10) ? 1 : 2) {

            case 0:
                System.out.println("I'm between one and five inclusive.");
                break;
            case 1:
                System.out.println("I'm between 6 and 10 inclusive.");
                break;
            case 2:
                System.out.println("I'm not between one and five or 6 and 10 inclusive.");
                break;
        }
    }
}
2

спользовать свой кейс по умолчанию для указания инструкций диапазона:

switch(n) {
    case 1 : System.out.println("case 1"); break;
    case 4 : System.out.println("case 4"); break;
    case 99 : System.out.println("case 99"); break;
    default :
        if (n >= 10 && n <= 15)
            System.out.println("10-15 range"); 
        else if (n >= 100 && n <= 200)
            System.out.println("100-200 range");
        else
            System.out.println("Your default case");
        break;   
}
27

тем ее деления, например:

switch ((int) num/10) {
    case 1:
        System.out.println("10-19");
        break;
    case 2:
        System.out.println("20-29");
        break;
    case 3:
        System.out.println("30-39");
        break;
    case 4:
        System.out.println("40-49");
        break;
    default:
        break;
}

Но, как вы можете видеть, это можно использовать только тогда, когда диапазон фиксирован в каждом случае.

Это хорошо работает с кодами состояния http, разделенными на 100.
1

(num > 1 && num < 5) ? first_case_method() 
                     : System.out.println("testing case 1 to 5")
                     : (num > 5 && num < 7)  ? System.out.println("testing case 1 to 5") 
                     : (num > 7 && num < 8)  ? System.out.println("testing case 1 to 5") 
                     : (num > 8 && num < 9)  ? System.out.println("testing case 1 to 5") 
                     : ... 
                     : System.out.println("default");
Вы можете это объяснить? - я получаю «мини ifs»; но кроме этого идка.
@ Тунаки этоif..elseif альтернативное использование в каскаде троичного оператора (condition ? statementIfTrue : statementIfFalse).
9
  case 1: case 2: case 3: case 4: case 5: 
         System.out.println("testing case 1 to 5");
         break;
  case 6: case 7: case 8: case 9: case 10:
         System.out.println("testing case 6 to 10");
         break;
  default:
         System.out.println("default"); 
Это работает для моего варианта использования, у меня есть 2 переменная int, и я хочу проверить, что 2 переменные находятся в том же диапазоне, как (10-20), (20-30), .... как это
не могли бы вы дать объяснение тоже ..?
@missingfaktor1. Я полагаю, это дело вкуса. Когда я имею дело с непрерывными интервалами, мне лично нравится думать оifкак будто я постепенно выливаюсь из нижнего поддиапазона. Кроме того, избыточное вычисление не является проблемой вообще, но избыточное сравнение немного беспокоит: становится проще выполнять смежные сравнения несинхронно, например. после некоторого редактирования:if (isBetween(x, 1, 4)) {...} else if (isBetween(x, 6, 10)), Во всяком случае, ничего страшного.
Вы можете это объяснить? - я получаю «мини ifs»; но кроме этого идка.
11

что вы можете сделать это на Java. Лучше всего поставить код в последнем случае диапазона.

switch (num) {
  case 1: case 2: case 3: case 4: case 5: 
     System.Out.Println("testing case 1 to 5");
     break;
  case 6: case 7: case 8: case 9: case 10:
     System.Out.Println("testing case 6 to 10");
     break;
  default:
     //
}

Похожие вопросы