Отображение определенных строк в постоянные целые числа? - PullRequest
1 голос
/ 10 ноября 2010

Для конкретного набора строк, как лучше всего сопоставить их с соответствующим набором целых чисел? Скажем, у меня есть класс с несколькими целочисленными константами, которые я использую внутри, но мне нужно взять входящие внешние строки и определить правильную соответствующую целочисленную константу, с которой они сопоставляются.

Вот упрощенный пример:

public class Example {
    public static final int ITEM_APPLE = 0;
    public static final int ITEM_BANANA = 1;
    public static final int ITEM_GRAPE = 3;

    public void incomingData(String value) {
        // Possible values would be "apple", "banana", and "grape" in this case.
    }
}

Каким будет наиболее подходящий подход для перехода от этого значения к соответствующей ему целочисленной константе? Хэш-карта? Или есть ли способ определить эти отображения в статическом члене? Еще одна идея?

Ответы [ 4 ]

6 голосов
/ 10 ноября 2010

Я бы использовал HashMap, так как это наиболее близко к тому, чего вы хотите достичь, и, следовательно, приемлемое решение. Вы можете определить статический HashMap:

Class Example {
    public static final int ITEM_APPLE = 0;
    public static final int ITEM_BANANA = 1;
    public static final int ITEM_GRAPE = 3;

    private static final Map<String, Integer> fruitCodes = new HashMap<String, Integer>();

    static {
        fruitCodes.put("apple", ITEM_APPLE);
        fruitCodes.put("banana", ITEM_BANANA);
        // ...
    }


    public void incomingData(String value) {
        // Possible values would be "apple", "banana", and "grape" in this case.
        Integer code = fruitCodes(value);

        if (null == code) {
            throw new IllegalArgumentException("Forbidden fruit: " + value);
        }
    }
}
3 голосов
/ 10 ноября 2010

Да, используйте enum.Каждому перечислению можно присвоить целочисленное значение или просто использовать ordinal()

public enum ExampleEnum {
    ITEM_APPLE(0), ITEM_BANANA(1), ITEM_GRAPE(3);

    private final int intValue;

    private ExampleEnum (int intValue) {
      this.intValue = intValue;
    }

    public int intValue() {
      return intValue;
    }
}

, а затем, например, ExampleEnum.valueOf("ITEM_APPLE").intValue(), чтобы преобразовать строку в int.

Если значения типа int являются последовательнымии начиная с нуля, вы можете полностью избавиться от поля intValue:

public enum ExampleEnum {
    ITEM_APPLE, ITEM_BANANA, ITEM_GRAPE;
}

и просто использовать ExampleEnum.valueOf("ITEM_APPLE").ordinal()

0 голосов
/ 10 ноября 2010

Я также предлагаю метод Enum, хотя ExampleEnum.valueOf ("ITEM_APPLE"). Ordinal () должен будет выполнить сравнение строк, чтобы получить ответ, в то время как HashMap даст вам сложность O (1).

Вероятно, опасная идея, но просто для забавы (как насчет этого):

class Example {
    public static final int ITEM_APPLE = "apple".hashCode();
    public static final int ITEM_BANANA = "banana".hashCode();
    public static final int ITEM_GRAPE = "grape".hashCode();

    public int incomingData(String value) {
        return value.hashCode();
    }

    public static void main(String[] args) {
        Example x = new Example();
        if (ITEM_APPLE == x.incomingData("apple"))
            System.out.println("ITEM_APPLE");
    }
    }
}

Вы просто должны убедиться, что хеш-коды строковых значений не конфликтуют; -)

0 голосов
/ 10 ноября 2010

вы могли бы использовать отражение, например:

Example.class.getField("ITEM_" + input.toUpperCase()).getInt(null);

однако вам следует рассмотреть возможность использования Enums или, если возможностей не так много, просто используйте набор else if операторов ...

...