将对象列表映射为Class的成员变量

时间:2017-01-31 11:13:08

标签: java list mapping

例如,考虑具有以下成员变量的A类:

onLocationChanged

现在考虑具有值的集合Integer id; String name;

List<Object> objList

是否有(标准)方法将这样的对象列表映射到类?我正在寻找像Hibernate的(0) 1 (1) "Peter" 这样的Java对象。

注意

我知道手动映射总是一个选项,但我的实际类更复杂,我正在寻找一个可重用的解决方案。

2 个答案:

答案 0 :(得分:1)

您可以使用java反射来实现结果:  基本上你用方法迭代类的字段:  Class.getDeclaredFields()

  

返回Field对象的数组,这些对象反映由此Class对象表示的类或接口声明的所有字段。这包括公共,受保护,默认(包)访问和私有字段,但不包括继承的字段。 返回的数组中的元素没有排序,也没有任何特定的顺序。如果类或接口没有声明字段,或者此Class对象表示基本类型,则此方法返回长度为0的数组,数组类或void。

然后以相同的字段声明顺序从列表中获取值 并指定它们。

旁注 :如上所述,没有特定的Class.getDeclaredFields()顺序,这意味着字段的顺序可能会在不同版本的java上发生变化,我强烈建议您使用Map 将值映射到其字段名称(请参阅安全代码)

不安全代码 (见说明)

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 + "]";
        }       

    }

}

(编辑) 安全代码

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 + "]";
        }

    }

}

答案 1 :(得分:0)

您可以使用以下方法解决问题

1)使用Java reflection获取字段数和来自给定类的字段

2)将列表的数据填充到属性

您可以参考此link