Как заставить случай переключателя принять несколько типов данных в Java?

При использовании случая переключателя Java, это excepts только символ и интервал, но я хочу обеспечить строковые случаи. Как сделать это возможным?

7
задан IAdapter 7 June 2010 в 10:09
поделиться

6 ответов

Вы не можете иметь строки в switch-case (пока). Он появится в Java 7.

Текущие типы, которые он принимает, включают char, byte, short, int, Character, Byte, Short, Integer, или тип enum.

Из спецификации языка Java:

Тип выражения должен быть char, byte, short, int, Character, Byte, Short, Integer или типом перечисления (§8.9), иначе произойдет ошибка компиляции.

...

Все перечисленное ниже должно быть истинным, иначе произойдет ошибка компиляции:

  • Каждое выражение константы case, связанное с оператором switch, должно быть присваиваемым (§5.2) типу выражения switch.
  • Ни одна метка switch не является нулевой.
  • Никакие два выражения константы case, связанные с оператором switch, не могут иметь одинаковое значение.
  • С одним и тем же выражением switch может быть связана не более одной метки по умолчанию.
6
ответ дан 6 December 2019 в 21:10
поделиться

switch-case - это языковая конструкция, которая предназначена для принятия только целые значения. Вы не можете изменить способ его работы.

1
ответ дан 6 December 2019 в 21:10
поделиться

Что я могу включить?

Начиная с Java 6, вы можете включать только следующие типы:

JLS 14.11 Оператор switch

 SwitchStatement:
переключатель (Выражение) SwitchBlock

Тип выражения должен быть char , байт , короткий , int , ] Символ , Байт , Короткий , Целочисленный или тип перечисление , либо возникает ошибка времени компиляции. [...] Каждое константное выражение case , связанное с оператором switch, должно быть присвоено типу выражения switch .


Итак, что я могу сделать?

В зависимости от вашего варианта использования вы можете использовать enum вместо String . В отличие от String , вы можете включить перечисление . Вот пример:

public class EnumSwitchSample {
    static enum Color {
        BLACK, WHITE;
    }
    public static void main(String[] args) {
        test(Color.valueOf("BLACK"));
        // "It's black!"

        test(Color.WHITE);
        // "It's white!"
    }
    static void test(Color c) {
        switch (c) {
            case BLACK:
                System.out.println("It's black!");
                break;
            case WHITE:
                System.out.println("It's white!");
                break;
        }       
    }
}

Однако enum в Java на самом деле довольно мощное средство, и вам может даже не понадобиться переключать на него. Вот пример:

public class EnumMemberExample {
    static enum Mood {
        SCREAM("I'M LOUD AND OBNOXIOUS!!!") {
            @Override public String say(String statement) {
                return statement.toUpperCase().replaceAll("!", "!!!");
            }
        },
        WHISPER("Ssh... Be vewy vewy quiet...") {
            @Override public String say(String statement) {
                return statement.toLowerCase().replaceAll("!", "...");
            }
        };          
        final String msg;
        Mood(String msg)    { this.msg = msg; }
        String getMessage() { return msg; }
        abstract String say(String statement);
    }
    public static void main(String[] args) {
        test(Mood.SCREAM);
        // "I'M LOUD AND OBNOXIOUS!!!"
        // "HELLO!!! HOW ARE YOU!!!"

        test(Mood.WHISPER);
        // "Ssh... Be vewy vewy quiet..."
        // "hello... how are you..."
    }
    static void test(Mood m) {
        System.out.println(m.getMessage());
        System.out.println(m.say("Hello! How are you!"));
    }
}

См. Также

Связанные вопросы

2
ответ дан 6 December 2019 в 21:10
поделиться

Как указано в других ответах, Java (в настоящее время) не поддерживает включение строковых значений. Существует три часто используемых подхода для достижения того же эффекта:

  • Замените переключатель цепочкой операторов if ... else if ... . (Фу).

  • Создайте и заполните HashMap, который сопоставляет строки с целочисленными кодами, а затем включите коды.

  • Определите тип enum , значения которого имеют имена, которые совпадают с именами строк, используйте EType.valueOf (String) для сопоставления строк со значениями перечисления и включите значения перечисления. (Это может быть сложнее, если от вас требуется соблюдать правила стиля идентификатора Java для значений перечисления, или если строки содержат символы, не являющиеся идентификаторами.)

  • @Pete Kirkham добавляет «классический прием» включения хэш-кода строки. Однако здесь есть несколько проблем:

    1. Он неправильно работает со случаем, когда предоставленная строка не является одной из требуемых строк. (Подумайте: многие строки хешируют один и тот же хэш-код.)

    2. Хэш-коды, скорее всего, будут широко разнесены, поэтому компилятору JIT придется скомпилировать переключатель как последовательность тестов / ветвей на основе значений хэш-кода. Это быстрее, чем тест / ветки на основе String.equals () , но это O (N) ... по сравнению с O (1) для переключатель, который компилируется в таблицу переходов.

3
ответ дан 6 December 2019 в 21:10
поделиться

Вы действительно отчаялись, что можете включить дайджест String. Если вам нравятся подобные вещи.

import java.util.zip.Adler32;

public class StringSwitch {

    public static void main(String[] args) {

        String arg;
        if (args == null || args.length == 0) {
            arg = "stackoverflow";
        } else {
            arg = args[0];
        }

        Adler32 algorithm = new Adler32();
        algorithm.update(arg.getBytes());
        int hash = (int) algorithm.getValue();

        switch (hash) {
        case 647693707:
            System.out.println("Programming Q & A");
            break;
        case 145556093:
            System.out.println("Narwhals and bacon");
            break;
        case 193790704:
            System.out.println("How do they work?");
            break;
        }
    }
}
0
ответ дан 6 December 2019 в 21:10
поделиться

Позвольте мне надеть мою догматическую шляпу (а вы кодируете на Java так что я предполагаю, что вы заботитесь о ООП)

Вместо того, чтобы спрашивать: как мне поступить не так? вместо этого спросите: что делать правильно? В этом случае: http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html и для обсуждения: http://www.c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism

0
ответ дан 6 December 2019 в 21:10
поделиться
Другие вопросы по тегам:

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