我在Java中有一个表示数据库内容的Object,如下所示:
public Database {
int varA;
String varB;
double varC;
}
现在我正在尝试选择和订购某些元素以进行更深入的处理,但我想让它可配置,所以我创建了一个枚举,表示对象的所有属性,如
public enum Contents {
VarA,
VarB,
VarC;
}
所以现在当我创建一个像
这样的选择时Contents[] select = { Contents.VarC, Contents.VarB };
我想生成一个String值列表,表示实际的数据库内容。现在,我能想到的唯一一个实现是切换选择中的每个条目,具有非常丑陋的二次复杂度......
public List<String> switchIT(Database db, Contents[] select) {
List<String> results = new ArrayList<String>();
for (Contents s : select) {
switch(s) {
case VarA:
results.add(db.varA.toString());
break;
//go on...
}
}
return results;
}
有更直接的方法在枚举和动态对象值之间进行映射吗? 或者用更一般的术语:动态选择对象值的最佳方法是什么?
答案 0 :(得分:3)
使用Java枚举的强大功能,这是完全成熟的类。
public enum Contents {
VarA { public String get(Database d) { return d.getVarA(); } },
VarB { public String get(Database d) { return d.getVarB(); } },
VarC { public String get(Database d) { return d.getVarC(); } };
public String get(Database d) { return ""; }
}
您的客户端代码将变为
public List<String> switchIT(Database db, Contents[] select) {
List<String> results = new ArrayList<String>();
for (Contents s : select) results.add(s.get(db));
return results;
}
更简洁但更慢的解决方案是基于反射使用get
的单个实现,并使用枚举成员的名称生成相应的getter名称:
public enum Contents {
VarA, VarB, VarC;
private final Method getter;
private Contents() {
try {
this.getter = Database.class.getMethod("get"+name());
} catch (Exception e) { throw new RuntimeException(e); }
}
public String get(Database d) {
try {
return (String) getter.invoke(d);
} catch (Exception e) { throw new RuntimeException(e); }
}
}