优化java枚举

时间:2015-07-04 05:56:46

标签: java enums

我的代码包含多个枚举,如下所示。基本上有助于通过整数而不是枚举值来使用枚举。是否可以应用某种优化,如继承或某些东西,以便所有人都可以有如下所示的行为。

public enum DeliveryMethods {

    STANDARD_DOMESTIC(1), STANDARD_INTERNATIONAL(2), EXPRESS_DOMESTIC(3), EXPRESS_INTERNATIONAL(4);

    private final int code;

    private DeliveryMethods(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    private static final HashMap<Integer, DeliveryMethods> valueMap = new HashMap<>(2);

    static {
        for (DeliveryMethods type : DeliveryMethods.values()) {
            valueMap.put(type.code, type);
        }
    }

    public static DeliveryMethods getValue(int code) {
        return valueMap.get(code);
    }
}

3 个答案:

答案 0 :(得分:4)

以下是一个示例,说明如何委托给另一个类:

public interface Keyed<K> {
    /**
     * returns the key of the enum
     */
    K getKey();
}

public class KeyEnumMapping<K, E extends Enum<?> & Keyed<K>> {
    private Map<K, E> map = new HashMap<>();

    public KeyEnumMapping(Class<E> clazz) {
        E[] enumConstants = clazz.getEnumConstants();
        for (E e : enumConstants) {
            map.put(e.getKey(), e);
        }
    }

    public E get(K key) {
        return map.get(key);
    }
}

public enum Example implements Keyed<Integer> {
    A(1),
    B(3),
    C(7);

    private static final KeyEnumMapping<Integer, Example> MAPPING = new KeyEnumMapping<>(Example.class);
    private Integer value;

    Example(Integer value) {
        this.value = value;
    }

    @Override
    public Integer getKey() {
        return value;
    }

    public static Example getByValue(Integer value) {
        return MAPPING.get(value);
    }

    public static void main(String[] args) {
        System.out.println(Example.getByValue(3));
    }
}

您还可以避免实现Keyed接口,只需将Function<E, K>传递给KeyEnumMapping构造函数,即将枚举转换为其键:

public class KeyEnumMapping<K, E extends Enum<?>> {
    private Map<K, E> map = new HashMap<>();

    public KeyEnumMapping(Class<E> clazz, Function<E, K> keyExtractor) {
        E[] enumConstants = clazz.getEnumConstants();
        for (E e : enumConstants) {
            map.put(keyExtractor.apply(e), e);
        }
    }

    public E get(K key) {
        return map.get(key);
    }
}

public enum Example {
    A(1),
    B(3),
    C(7);

    private static final KeyEnumMapping<Integer, Example> MAPPING =
        new KeyEnumMapping<>(Example.class, Example::getValue);
    private Integer value;

    Example(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }

    public static Example getByValue(Integer value) {
        return MAPPING.get(value);
    }

    public static void main(String[] args) {
        System.out.println(Example.getByValue(3));
    }
}

答案 1 :(得分:0)

您可以考虑使用Enum的getOrdinal()方法,而不是自己维护“代码”。

http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#ordinal()

即使您维护'code'属性,也不必维护'valueMap'。相反,您可以使用Enum的'values()'方法并迭代所有枚举。

答案 2 :(得分:0)

除非有必要,否则不需要Hashmap。最好与switch-case一起使用enum

我写过从Integer获取枚举以及字符串

  public enum DeliveryMethods {

    STANDARD_DOMESTIC(1), STANDARD_INTERNATIONAL(2), EXPRESS_DOMESTIC(3), EXPRESS_INTERNATIONAL(4);

    private final int code;

    private DeliveryMethods(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public static DeliveryMethods fromString(String code) {
        if (code.matches("[1-4]")) {
            return fromInteger(Integer.valueOf(code));
        }
        throw new RuntimeException("No values for code " + code);
    }

    public static DeliveryMethods fromInteger(int code) {
        switch (code) {
            case 1:
                return STANDARD_DOMESTIC;
            case 2:
                return STANDARD_INTERNATIONAL;
            case 3:
                return EXPRESS_DOMESTIC;
            case 4:
                return EXPRESS_INTERNATIONAL;
        }
        throw new RuntimeException("No values for code " + code);
    }

  public static DeliveryMethods fromIntegerType2(int code) {
        for (DeliveryMethods d : DeliveryMethods.values()) {
            if (d.getCode() == code) {
                return d;
            }
        }
        throw new RuntimeException("No values for code " + code);
    }
}