我有一个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;
}
}
答案 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
注意:您可以从类本身获得一些额外的属性。