如何从java中的对象列表创建映射列表而不使用getKey方法?
如何创建一个映射列表,其中每个键名都是从class属性的名称推断出来的,值是由getter方法放置的 我正在用java上下面的课如何从java中的对象列表创建映射列表而不使用getKey方法?,java,generics,java-8,java-stream,Java,Generics,Java 8,Java Stream,如何创建一个映射列表,其中每个键名都是从class属性的名称推断出来的,值是由getter方法放置的 我正在用java上下面的课 class DTA { private String id; private String age; @Override public String toString() { return "DTA{" + "id='" + id + '\'' + ", age='" + age + '\''
class DTA {
private String id;
private String age;
@Override
public String toString() {
return "DTA{" +
"id='" + id + '\'' +
", age='" + age + '\'' +
'}';
}
public DTA(String id, String age) {
this.id = id;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
我有一个DTA类型的对象列表
List<DTA> listA = new ArrayList<>();
listA.add(new DTA("A", "15"));
listA.add(new DTA("B", "25"));
List listA=new ArrayList();
增加(新的DTA(“A”、“15”));
增加(新的DTA(“B”,“25”));
我想创建一个有序的地图列表(有点像scala),其中包含以下内容
List<? extends Map<String, String>>
List(Map("id"->"A", "age"->"15"), Map("id"->"B", "age"->"25"))
List如果没有“动力学”,直截了当的事情可能看起来像:
List<Map<String, String>> x = listA
.stream()
.map(this::toMap)
.collect(Collectors.toList());
List x=listA
.stream()
.map(this::toMap)
.collect(Collectors.toList());
使用本地助手,例如:
private Map<String, String> toMap(DTA dta) {
Map<String, String> rv = new HashMap<>();
rv.put("id", dta.getId());
rv.put("age", dta.getAge());
return rv;
}
private-Map-toMap(DTA-DTA){
Map rv=新的HashMap();
rv.put(“id”,dta.getId());
rv.put(“age”,dta.getAge());
返回rv;
}
为了在这里完全动态,您必须使用来查询字段名。你可以找到如何做到这一点的例子
但我强烈建议不要这样做:反思应该永远是你的最后手段。DTA的概念表明,不管怎样,对象数据都来自某个“服务”。如果是这样,为什么要先序列化到一个特定的DTA类中,然后将该信息“展平”到一些通用的映射结构中呢
意思是:当该服务向您提供序列化为JSON或XML的对象时。。。然后,只需使用gson或jackson这样的库,就可以直接将数据反序列化为此类通用的基于“平面”地图的对象。例如,杰克逊有一个班级。当您反序列化到这些对象中时,您可以免费获得字段名的映射!请参阅更多示例代码
要点是:使用反射识别字段是可能的。但是反射代码总是冗长乏味,而且容易出错。如果可能的话,不要自己动手 基本上,Java中用于“查看”类内容的工具称为反射。例如,如果您的对象是POJO(纯旧Java对象),则可以按以下方式迭代类中的所有字段:
DTA obj; // some object, I assume it's initialized
Field[] fields = DTA.class.getDeclaredFields();
Map<String, Object> valuesMap = new HashMap<>();
for (field : fields) {
boolean wasAccessible = field.isAccessible(); // check if class has access control disabled
field.setAccessible(true); // disable access control (private/protected) to extract value
valuesMap.put(field.getName(), field.get(obj));
field.setAccessible(wasAccessible); // return flag to initial value
}
DTA obj;//某个对象,我想它已经初始化了
Field[]fields=DTA.class.getDeclaredFields();
映射值Map=newhashmap();
用于(字段:字段){
boolean wasaccessable=field.isAccessible();//检查类是否禁用了访问控制
field.setAccessible(true);//禁用访问控制(私有/受保护)以提取值
valuesMap.put(field.getName(),field.get(obj));
field.setAccessible(wasaccessable);//将标志返回初始值
}
然而,以这种方式通过反射访问值是出了名的黑客行为。除非你有充分的理由自己去做,否则试着使用一个自动化任务的框架,而不是从头开始编写这样的代码
而且,反射速度很慢。对于每个对象访问字段
这样的实体是次优的,如果您真的想编写这样的代码,您应该将字段
对象缓存在映射
中,并且只对每个DTA
对象集合执行setAccessible
覆盖和字段
检索一次。列出了不应该使用反射的原因,并给出了一个示例。回答得好,值得投一票!