C_B
C_B

Reputation: 2682

Mapping list of objects as member variables of Class

As an example, consider Class A with the following member variables:

Integer id;
String name;

Now consider the collection List<Object> objList with values:

(0) 1
(1) "Peter"

Is there a (standard) way to map such a list of objects to a class? I'm looking for something like Hibernate's .setResultTransformer(A.class) for Java objects.

NOTE

I know manual mapping is always an option but my actual Class is much more complex, and I'm looking for a reusable solution.

Upvotes: 2

Views: 2259

Answers (2)

Emax
Emax

Reputation: 1403

You can achieve the result with the java reflection: essentially you iterate over the fields of the class with the method: Class.getDeclaredFields()

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields. The elements in the array returned are not sorted and are not in any particular order. This method returns an array of length 0 if the class or interface declares no fields, or if this Class object represents a primitive type, an array class, or void.

Then you get the values from the list in the same order of fields declaration and assign them.

Side note: as mentioned above there is no particular order of Class.getDeclaredFields() this mean that the order of the fields could change on different version of java, i strongly advise to map the values to their field name with a Map (see the safe code)

UNSAFE CODE (see the note)

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ReflectionTest {

    public static void main(String[] args) {

        // List of the fields values
        List<Object> objList = new ArrayList<Object>();
        objList.add(1);
        objList.add("Peter");

        // New instasnce of A
        A aInstance = new A();

        // Get all the field of the class
        Field[] aFields = A.class.getDeclaredFields();

        // The number of fields is equal of the number of values?
        if (aFields.length == objList.size()) {

            for (int index = 0; index < aFields.length; index++) {

                try {

                    // Make the private modifier accesible from reflection
                    aFields[index].setAccessible(true);

                    // Set the value of the field based on the value of the list
                    aFields[index].set(aInstance, objList.get(index));

                } catch (Exception exception) {
                    // Something went wrong
                    exception.printStackTrace();
                }

            }

        } else {
            System.out.println("Field/Values mismatch");
        }

        // Print the fields of A
        System.out.println(aInstance.toString());

    }

    static class A {

        private Integer id;
        private String name;

        @Override
        public String toString() {
            return "A [id=" + id + ", name=" + name + "]";
        }       

    }

}

(edit) SAFE CODE

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class ReflectionTestSafe {

    public static void main(String[] args) {

        // Map the values to their field name
        Map<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("name", "Peter");
        objMap.put("id", 1);

        // New instasnce of A
        A aInstance = new A();

        // Get all the field of the class
        Field[] aFields = A.class.getDeclaredFields();

        // The number of fields is equal of the number of values?
        if (aFields.length == objMap.size()) {

            for (int index = 0; index < aFields.length; index++) {

                try {

                    // Get the name of the current field (id, name, etc...)
                    String aFieldName = aFields[index].getName();

                    // Check if the field value exist in the map
                    if (!objMap.containsKey(aFieldName)) {
                        throw new Exception("The value of the field " + aFieldName + " isn't mapped!" );
                    }

                    // Get the value from the map based on the field name
                    Object aFieldValue = objMap.get(aFieldName);

                    // Make the private modifier accesible from reflection
                    aFields[index].setAccessible(true);

                    // Set the value of the field
                    aFields[index].set(aInstance, aFieldValue);

                } catch (Exception exception) {
                    // Something went wrong
                    exception.printStackTrace();
                }

            }

        } else {
            System.out.println("Field/Values mismatch");
        }

        // Print the fields of A
        System.out.println(aInstance.toString());

    }

    static class A {

        private Integer id;
        private String name;

        @Override
        public String toString() {
            return "A [id=" + id + ", name=" + name + "]";
        }

    }

}

Upvotes: 1

mahesh
mahesh

Reputation: 1331

You can use below approach to solve the problem

1) Use the Java reflection to get field count and fields from the given class

2) Populate the data for the list to the properties

You can refer this link

Upvotes: 0

Related Questions