如何从java中的对象列表创建映射列表而不使用getKey方法?

如何从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属性的名称推断出来的,值是由getter方法放置的

我正在用java上下面的课

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
覆盖和
字段
检索一次。

列出了不应该使用反射的原因,并给出了一个示例。回答得好,值得投一票!