mardi 15 août 2017

Iterative instantiation of n generic list for n fields in an object

Given an object which stores values of different types,

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

an object which stores values of one type in a data structure

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

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

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

and an object which stores multiple instances of the above object (GenericList) in another data structure.

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;
    }
}

How can we iteratively instantiate GenericList objects such that T is equal to the type of the current field in the given Record object?

Note:
The above code belongs to a system which pulls data from the internet every five minutes and stores them in the above shown data structure. This means that every five minutes the system creates a Record object (with a fixed number of fields) and either creates a new data structure from it or appends it to an existing one.

To be more precise:
In this example I want to create and store three GenericList objects:

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

This can be done with the following code:

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;
}

But when the number of fields in the Record object increases, this method not only gets less readable and less maintainable but rather you have to expand the implementation to fit your requirements.
So to refactor this into solid, readable and maintainable code one would need to iterate over the fields in the Record object.
Reading through this post I have learned how to do just this. Applying the code given in the accepted answer to my problem, I expected the following code to work.

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;
}

But as of this post I am stuck with manual instantiation and I am wondering if there is a way to implement what i want to do.





Aucun commentaire:

Enregistrer un commentaire