java - 迭代实例化: n generic lists for n fields in an object

标签 java data-structures reflection

给定一个存储不同类型值的对象,

public class Record {
    String  string;  
    Float   floot;
    Integer integer;
}

在数据结构中存储一种类型的值的对象

public class GenericList<T> {
    private final List<T> genericList;

    public GenericList() {
        genericList = new ArrayList();
    }

    public void add(T element) {
        genericList.add(element);
    }
}

以及一个在另一个数据结构中存储上述对象(GenericList)的多个实例的对象。

public class Structure {
    private final List<GenericList> structure;

    public Structure(Record record) {
        structure = createFrom(record);
    }

    private List<GenericList> createFrom(Record record) {
        List<GenericList> result = new ArrayList();
        // create one column for each field in record
        // with its corresponding type
        return result;
    }
}

我们如何迭代实例化 GenericList 对象使得 T 等于当前字段的类型在给定的 Record 对象中?

注意:
上面的代码属于一个系统,该系统每五分钟从互联网提取数据并将它们存储在上面显示的数据结构中。这意味着系统每五分钟创建一个 Record 对象(具有固定数量的字段),并从中创建一个新的数据结构或将其附加到现有数据结构。

更准确地说:
在此示例中,我想创建并存储三个 GenericList 对象:

GenericList<String>  stringList;
GenericList<Float>   floatList;
GenericList<Integer> integerList;

这可以通过以下代码来完成:

private List<GenericList> createFrom(Record record) {
    List<GenericList> result = new ArrayList();

    GenericList<String> stringList = new GenericList();
    stringList.add(record.string);
    structure.add(stringList);

    GenericList<Float> floatList = new GenericList();
    floatList.add(record.floot);
    structure.add(floatList);

    GenericList<Integer> integerList = new GenericList();
    integerList.add(record.integer);
    structure.add(integerList);

    return result;
}

但是当 Record 对象中的字段数量增加时,此方法不仅可读性和可维护性较差,而且您必须扩展实现以满足您的要求。
因此,要将其重构为可靠、可读且可维护的代码,需要迭代 Record 对象中的字段。
通读this post我已经学会了如何做到这一点。 应用已接受的答案中给出的代码来解决我的问题,我希望以下代码能够工作。

private List<GenericList> createFrom(Record record) {
    List<GenericList> result = new ArrayList();
    for (Field field : record.getClass().getDeclaredFields()) {
        // ERROR here
        GenericList<field.getType()> genericList = new GenericList();
        // IDE says: "> expected    not a statement"
        genericList.add(field.get(record));
        structure.add(genericList);
    }
    return result;
}

但截至这篇文章,我一直坚持手动实例化,我想知道是否有办法实现我想做的事情。

最佳答案

简单的回答是你不能,也不需要。

更多细节:Java 中的泛型纯粹是编译时构造,仅用于编译时类型检查。当您创建ArrayList<String>时编译器实际创建的是 ArrayList<Object> ,例如,将列表中的元素分配给 String 时插入适当的类型检查变量。

您可以使用示例代码做的就是制作 genericList一个GenericList<Object> ,或者像您对 structure 所做的那样省略类型参数您的 Structure 中的成员类(class)。生成的代码将是相同的(一旦您将 genericList 插入 structure 中,您无论如何都会删除类型信息)。

关于java - 迭代实例化: n generic lists for n fields in an object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45697180/

相关文章:

java - OrientDB在java代码中创建边约束

java - 使用复杂对象作为参数从 Java 中调用 JavaScript 函数

java - 如何找到 Play Framework 应用程序的绝对路径?

java - 树的分区压缩以及如何将节点压缩到根

c# - 反射不触发参数化构造函数c#

java - 什么是类对象(java.lang.Class)?

haskell - 数据结构请求 : Lazily infinite set

java - 平面组织结构到 Java 中的 TreeView

c# - 使用反射双向自动映射所有域实体以查看 MVC3 中的模型

Java反射类