开发者

Mapping specific strings to constant integers?

Given a specific set of strings, what's the best way to map them to a corresponding set of integers? Say I have a class with a few integer constants that I use internally, but need to take incoming external strings and determine the correct corresponding integer constant they map to.

Here's a simplified example:

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 incomingDa开发者_如何学编程ta(String value) {
        // Possible values would be "apple", "banana", and "grape" in this case.
    }
}

What would the most appropriate approach be to go from that value to its corresponding integer constant? A HashMap? Or is ther any way to define these mappings in a static member? Another idea?


I would use a HashMap as that is closest to what you want to achieve, and therefore a maintainable solution. You can define a static 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);
        }
    }
}


Yes, use an enum. You can assign each enum an integer value, or just use 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;
    }
}

then use e.g. ExampleEnum.valueOf("ITEM_APPLE").intValue() to resolve String to int.

If the int values are sequential and zero-based, you can get rid of the intValue field altogether:

public enum ExampleEnum {
    ITEM_APPLE, ITEM_BANANA, ITEM_GRAPE;
}

and just use ExampleEnum.valueOf("ITEM_APPLE").ordinal()


you 'could' use reflection eg:

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

however, you should consider using Enums or if there aren't too many possibilities just use a set of else if statements...


I also suggest an Enum method, although ExampleEnum.valueOf("ITEM_APPLE").ordinal() will have to do string comparisons to get to the answer while a HashMap will give you an O(1) complexity.

Probably a dangerous idea but just for fun (how about this):

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

You just have to ensure the string value's hash codes does not clash ;-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜