繁体   English   中英

Java中具有动态字段的对象/具有不同值的Hashmap

[英]Object with dynamic fields / Hashmap with different values in Java

我们正在用Java数据库中进行一些知识发现。

我们有不同的数据库,对此一无所知。

一个示例场景:我们要检查一个实体是否具有属性名称并将其重命名。 在python / js /动态语言中,这很简单:

if Object.hasKey(name) => Object.name = "Jordan"

有没有办法在Java中存储和操作通用对象? 显然,类是不对的,因为我们不知道对象的结构。 哈希图也不会削减它,因为对象可以具有所有SQL类型作为属性类型,并且哈希图仅限于同类字段。

除了@dotvav注释,还可以查看Apache Commons BeanUtils ,它可以简化反射工作。

例:

Map<String, String> props = BeanUtils.describe(someObject);
if (props.containsKey("name")) {
    BeanUtils.setProperty(someObject, "name", "value");
}

您仍然可以使用哈希图。

Map<Strung, Object> map = new Hashmap<>();
map.put("name", new Integer());
map.put("another name", new String());

String value = (String)map.get("another name");
String value = (String)map.get("name"); // You get error here because integer type stored in map.
// check with 'instanceof' for type if necessary

一切正常

您可以使用反射来更改对象的私有字段。

假设我们有一个Human对象,带有一个name字段:

public static class Human {
    private String name;

    public Human(String name) {
        this.name = name;
    }

    public String toString() {
        return new StringBuilder("Name: ").append(this.name).toString();
    }
}

像其他一些建议的答案一样,您可以使用HashMap<String, Object>来存储任何对象。 您只需遍历地图,然后将每个对象传递给以下方法:

public static void changeName(Object obj, String newName) throws IllegalArgumentException, IllegalAccessException {
    for (Field f:obj.getClass().getDeclaredFields()) {
        if (f.getName().toLowerCase().equals("name")) {
            f.setAccessible(true);
            f.set(obj, newName);
            f.setAccessible(false);
        }
    }
}

此方法检索对象的所有字段,并将字段名称与“名称”进行比较。 如果标识了一个字段,它将更改可访问性(在私有字段的情况下)并将字段值更改为newName

Human me = new Human("Ian");
System.out.println(me);
changeName(me, "Jan");
System.out.println(me);

输出:

Name: Ian
Name: Jan

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM