Java Method Refactoring Using Enum

java

Solution

Your method is essentially mapping from a predetermined `String` to a `Category`, so why not use a `Map` instead? Specifically, I'd recommend Guava's `ImmutableMap`, since these mappings are static:

private static final ImmutableMap<String, Category> CATEGORIES_BY_STRING =
        ImmutableMap.of(
            "producer", Category.CATEGORY_PRODUCER,
            "meter", Category. CATEGORY_METER,
            "consumer", Category.CATEGORY_CONSUMER
        );

Or the standard way if you don't want to use a third-party library:

private static final Map<String, Category> CATEGORIES_BY_STRING;
static {
    Map<String, Category> backingMap = new HashMap<String, Category>();
    backingMap.put("producer", Category.CATEGORY_PRODUCER);
    backingMap.put("meter", Category.CATEGORY_METER);
    backingMap.put("producer", Category.CATEGORY_CONSUMER);
    CATEGORIES_BY_STRING = Collections.unmodifiableMap(backingMap);
}

You could still employ your method to check for invalid values (and support case-insensitivity as David Harkness pointed out):

private Category getCategory(String val) {
    Category category = CATEGORIES_BY_STRING.get(val.toLowerCase());
    if (category == null) {
        throw new IllegalArgumentException();
    }
    return category;
}

About using enums:

If you have complete control over the `String`s that are passed into `getCategory`, and would only be passing literal values, then it does make sense to switch to an `enum` instead.

EDIT: Previously, I recommended using an `EnumMap` for this case, but Adrian's answer makes much more sense.

Problem

The getCategory method below seems very redundant and I was wondering if anyone has some suggestions on refactoring it to make it cleaner possibly using an Enum. Based on the "val" passed in, I need getCategory to return the proper Category instance from the Category class. The Category class is generated JNI code, so I don't want to change that. Anyone have any ideas? Method to be refactored: ``` private Category getCategory(String val) throws Exception{ Category category; if (val.equalsIgnoreCase("producer")) { usageCategory = Category.CATEGORY_PRODUCER; } else if (val.equalsIgnoreCase("meter")) { usageCategory = Category.CATEGORY_METER; } else if (val.equalsIgnoreCase("consumer")) { usageCategory = Category.CATEGORY_CONSUMER; } else { throw new Exception("Invalid value: " + val); } return usageCategory; } ``` Category.java: Generated JNI (can't change this): ``` public final class Category { public final static Category CATEGORY_PRODUCER = new Category("CATEGORY_PRODUCER", SampleJNI.CATEGORY_PRODUCER_get()); public final static Category CATEGORY_METER = new Category("CATEGORY_METER", SampleJNI.CATEGORY_METER_get()); public final static Category CATEGORY_CONSUMER = new Category("CATEGORY_CONSUMER", SampleJNI.CATEGORY_CONSUMER_get()); } ```

Original source