如何将枚举常量转换为其字段值的键值对?

时间:2018-07-30 15:50:07

标签: java enums

我有一个Java枚举类,其中包含多个枚举常量,每个常量定义了多个字段。

我希望能够将枚举常量转换为包含字段名称和值的键值对列表。

困难来自创建一个设置,该设置将允许用户只需要添加一个新的枚举常量,甚至向每个常量添加新字段,而没有使使用此数据的代码知道将存在哪些字段。

public enum Stuff
{
  ORDINAL_ZERO( "Zero's identifier", "Zero's value A", "Zero's value B" ),
  ORDINAL_ONE( "One's identifier", "One's value A", "One's value B" );

  private String identifer;
  private String valueA;
  private String valueB;

  Stuff( String identifier, String valueA, String valueB )
  {
    this.identifier = identifier;
    this.valueA = valueA;
    this.valueB = valueB;
  }

  public static Stuff getStuffForIdentifier( String identifier )
  {
    for ( Stuff stuff : values() )
    {
      if ( stuff.getIdentifier().equalsIgnoreCase( identifier ) )
        return stuff;
    }
  }

  public static Map<String, String> getStuffForIdentifierAsMap( String identifier )
  {
    TODO: return a key-value pair map of a single enum constant where I can iterate through the keys and get their values without knowing what all fields are defined ahead of time i.e. if we asked for a map of the 0 ordinal constant's fields:
    Map<String, String> map = new HashMap<String, String>();
    map.put("identifier", "Zero's identifer");
    map.put("valueA", "Zero's value A");
    map.put("valueB", "Zero's value B");
    return map;
  }
}

1 个答案:

答案 0 :(得分:1)

您可以迭代Stuff.values()来找到具有正确标识符的对象

public static Map<String, Object> getStuffForIdentifierAsMap(String identifier) 
  throws IllegalAccessException {
    for (Stuff stuff : Stuff.values()) {
        if(stuff.getIdentifier().equals(identifier)) {
          ...
        }

注意:每次调用该方法时,调用Stuff.values()是有害的,因为它每次都会创建该数组的新副本。在生产代码上,应避免使用某些缓存。

然后,您可以像这样迭代类的字段:

private static Map<String, Object> dumpValues(Stuff stuff) throws IllegalAccessException {
    Map<String, Object> map = new HashMap<String, Object>();
    for (Field field : stuff.getClass().getDeclaredFields()) {
        map.put(field.getName(), field.get(stuff));
    }
    return map;
}

测试

public static void main(String[] args) throws Exception {
    Map<String, Object> props = getStuffForIdentifierAsMap("Zero's identifier");

    for (Map.Entry<String, Object> entry : props.entrySet()) {
        System.out.println(entry.getKey() + " : " + entry.getValue());
    }
}

输出

ORDINAL_ONE : ORDINAL_ONE
identifier : Zero's identifier
valueB : Zero's value B
valueA : Zero's value A
ORDINAL_ZERO : ORDINAL_ZERO
$VALUES : [Lcom.denodev.Stuff;@60e53b93

注意:您可以从类本身获得一些额外的属性。