Как заставить switch case принимать несколько типов данных в Java? - PullRequest
7 голосов
/ 07 июня 2010

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

Ответы [ 6 ]

6 голосов
/ 07 июня 2010

Вы не можете иметь строки в корпусе коммутатора (пока). В Java 7.

В настоящее время принимаются следующие типы: char, byte, short, int, Character, Byte, Short, Integer или тип enum.

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

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

...

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

  • Каждое выражение константы case, связанное с оператором switch, должно быть присвоено (§5.2) типу выражения switch.
  • Никакая метка переключателя не равна нулю.
  • Никакие два выражения константы регистра, связанные с оператором switch, не могут иметь одинаковое значение.
  • Не более одной метки по умолчанию может быть связано с тем же переключателемзаявление.
3 голосов
/ 07 июня 2010

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

  • Заменить switch цепочкой if ... else if ... операторов. (Тьфу).

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

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

  • @ Пит Киркхэм добавляет "классический взлом" включения хеш-кода String. Однако есть несколько проблем с этим:

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

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

2 голосов
/ 07 июня 2010

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

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

JLS 14.11 switch оператор

SwitchStatement:
    switch ( Expression ) SwitchBlock

Тип Expression должен быть char, byte, short, int, Character, Byte, Short, Integer или enum или произошла ошибка во время компиляции. [...] Каждое case константное выражение, связанное с оператором switch, должно присваиваться типу switch Expression.


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

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

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 на самом деле довольно мощный, и вам может даже не понадобиться switch на нем. Вот пример:

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

Смотри также

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

1 голос
/ 07 июня 2010

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

0 голосов
/ 07 июня 2010

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

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

0 голосов
/ 07 июня 2010

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

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