迭代实例化:n对象中n个字段的通用列表

时间:2017-08-15 16:26:19

标签: 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;
}

但是就这篇文章而言,我陷入了手动实例化的困境,我想知道是否有办法实现我想做的事情。

1 个答案:

答案 0 :(得分:1)

简短的回答是你做不到,你不需要。

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

您可以对示例代码执行的操作只是让genericList成为GenericList<Object>,或者省略类型参数,就像您为structure成员所做的那样Structure }类。生成的代码将是相同的(只要您将genericList插入structure,您就会丢弃类型信息。)