许多具有相同功能的枚举?

时间:2012-03-07 08:47:20

标签: java enums

我想创建一些枚举,如本答案中所述: Lookup enum by string value

(即,一个包含toString()的枚举和一个与枚举本身不同的名称)

有什么办法可以重用这个功能,而不必在每个枚举中重新实现它?

3 个答案:

答案 0 :(得分:3)

我不相信你可以在每个枚举中摆脱“添加字段和属性”。您可以将fromText方法委托给一个常用方法,如果您为该属性创建一个接口,并传递values()或(更好)EnumSet。 (更好:编写一个方法来创建不区分大小写的Map,并在每个枚举中调用一次,将结果存储在静态变量中。)

答案 1 :(得分:3)

如果您传入可能值列表,那么您可以在不依赖于enum类型的情况下执行此操作。

public static <T> T findByString(T[] values, String toString) {
    Objects.requireNonNull(toString);
    for (T t : values) {
        if (toString.equals(t.toString())) {
            return t;
        }
    }
    throw new IllegalArgumentException();
}

致电:

Blah blah = SomeClass.findByString(Blah.values(), str);

不是每次调用Blah.values(),而是可以将它放在一个对象中,该对象可以传递并一般使用。也许以后会添加其他方法。

public interface ByString<T> { // Choose a better name.
    T find(String toString);
}
[...]
    private static final ByString<Blah> blahs = byString(Blah.values());
[...]
    public static <T> ByString<T> byString(T[] values) {
        final T[] valuesCopy = values.clone();
        return new ByString<T>() {
            public T find(String toString) {
                return SomeClass.findByString(valuesCopy, toString);
            }
        };
    }
[...]

致电:

Blah blah = blahs.find(str);

事实上,您可能希望优化它。执行toString一次,然后使用地图。

    public static <T> ByString<T> byString(T[] values) {
        final Map<String,T> byToStrings = new HashMap<>(
            (int)(values.length/0.75f)+1 // Doesn't HashMap construction suck.
        );
        for (T value : values) {
            byToStrings.put(values.toString(), value);
        }
        return new ByString<T>() {
            public T find(String toString) {
                T value = byToStrings.get(toString);
                if (value == null) {
                    throw new IllegalArgumentException();
                }
                return value;
            }
        };
    }

答案 2 :(得分:1)

如果您有许多共享相同功能的枚举,我会。

  • 使用一个枚举,因为它们有很多共同之处。
  • 使用每个枚举可以调用的辅助方法。

Java 8将使虚拟扩展更简单。它允许您在接口上定义默认实现(必须是辅助/静态方法)