2010-11-09 3 views
1

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

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

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

Что бы наиболее подходящим будет идти от этого значения к соответствующему целочисленная константа? HashMap? Или это способ определить эти сопоставления в статическом члене? Еще одна идея?

ответ

6

Я хотел бы использовать 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); 
     } 
    } 
} 
+0

Я принимаю этот ответ, потому что он дает лучшее решение для моего конкретного случая.Все другие действительные ответы, по крайней мере, получат от меня большой голос. – Wilco

3

Да, используйте enum. Можно присвоить каждому 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.

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

public enum ExampleEnum { 
    ITEM_APPLE, ITEM_BANANA, ITEM_GRAPE; 
} 

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

+0

Но, учитывая мой пример, как я могу получить Example.ITEM_APPLE, если задана строка «apple»? – Wilco

+1

Или лучше проиллюстрировать, что, если бы я имел «4pple» в качестве значения и знал, что соответствует ITEM_APPLE? Как я мог перевести? – Wilco

+0

@Wilco: Самый простой вариант - предоставить константам перечисления то же имя, что и строки, которые вы хотите использовать. Альтернативно, передайте строку '" apple "' в качестве другого аргумента конструктора и сохраните это в статической 'Map' Строковые значения для значений перечисления. Тем не менее, это начинает громоздко. – skaffman

0

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

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

+0

Имеет смысл, но вы правы в части «может». Кроме того, в моем случае входящие строки не всегда могут отображать прямую конечную часть константы (т. Е. «ITEM_» + строка) (подумайте об этом скорее как совпадение) – Wilco

+0

, тогда вам придется писать некоторые пользовательские сопоставления логика. вы можете либо создать хэш возможностей, либо проверить диапазон имен, насколько хорошо они соответствуют вводам и т. д. ... многие варианты, ни один из них не соответствует 100%. – pstanton

0

Я также предлагаю метод 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"); 
    } 
    } 
} 

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

Смежные вопросы