【问题标题】:How to convert a String to the correct Enum constant (multiple Enums implementing a common interface)?如何将字符串转换为正确的枚举常量(多个枚举实现一个通用接口)?
【发布时间】:2012-08-11 20:31:40
【问题描述】:

假设我有一个界面...

public interface Feature
{
    public abstract void doSmth();
}

...以及实现该接口的多个枚举:

// 第一个枚举

public enum FeatureA implements Feature
{
    A1
    {
        @Override public void doSmth() { System.out.println("A ==== A1"); }
    },

    A2
    {
        @Override public void doSmth() { System.out.println("A ==== A2"); }
    };

    @Override public abstract void doSmth();
}

//第二个枚举

public enum FeatureB implements Feature
{
    B1 
    {
        @Override public void doSmth() { System.out.println("B ==== B1"); }
    },

    B2
    {
        @Override public void doSmth() { System.out.println("B ==== B2"); }
    },

    B3
    {
        @Override public void doSmth() { System.out.println("B ==== B3"); }
    };

    @Override public abstract void doSmth();
}

// 和许多其他实现 Feature 的枚举

现在假设我像这样组装一组对应于枚举常量名称的字符串(这是第三方代码所必需的)...

Set<String> singleEnum = new LinkedHashSet<String>();
singleEnum.add("A2");
singleEnum.add("A1");

... 稍后我需要将此类集合中的每个 String 转换为枚举常量,然后应用 doSmth() 方法。 singleEnum 仅包含 FeatureA 常量的名称,因此在这种情况下我可以应用 valueOf(String) 方法:

for (String s : singleEnum)
{
    FeatureA.valueOf(s).doSmth();
}

但是如果集合中的字符串对应于不同的枚举常量呢?例如:

Set<String> multipleEnums = new LinkedHashSet<String>();
multipleEnums.add("A1");
multipleEnums.add("B2");
multipleEnums.add("A2");

我想做这样的事情:

for (String s : multipleEnums)
{
    Feature./* convert s to the correct enum */.doSmth();
}

有没有简单的方法可以做到这一点? Eclipse 允许应用于 Feature 的唯一方法是 Feature.class,我真的不知道如何从那里着手。 我正在处理庞大的数据集,因此性能很重要。

谢谢。

【问题讨论】:

    标签: java interface enums type-conversion


    【解决方案1】:

    您可以使用每个枚举的名称创建一个 Map

    static final Map<String, Feature> map = ...
    static <F extends Enum & Feature> void addEnums(F... features) {
        for(F f: features)
           map.put(f.name(), f);
    }
    
    addEnums(FeatureA.values());
    addEnums(FeatureB.values());
    

    【讨论】:

    • 这几乎是我在当前项目中所做的方式,我正好有这个要求。不过有一点:我对映射使用延迟初始化习惯用法,因为否则必须显式调用 addEnums 或在静态初始化程序中执行此操作,这可能会导致循环依赖问题。
    【解决方案2】:

    有没有简单的方法可以做到这一点?

    我不这么认为。如果它只是一个枚举,您可以使用枚举的静态 valueOf 方法进行转换。但是对于多个枚举,您需要调用它们中的每一个......并处理 IllegalArgumentExceptions。

    我认为您将不得不为所有枚举值创建和填充 Map&lt;String, Feature&gt;

    【讨论】:

      猜你喜欢
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 2016-07-30
      • 2015-08-21
      相关资源
      最近更新 更多