Reputation: 113
We are doing some knowledge discovery in Databases in Java.
We have different databases we know nothing about.
An example scenario: We want to check if an entity has the property name and rename it. In python / js / dynamic languages that would be trivial:
if Object.hasKey(name) => Object.name = "Jordan"
Is there a way to store and manipulate generic objects at all in java? Obviously classes are out of the way, since we don't know the object structure. Hashmaps also don't cut it, because the object can have all SQL types as property-types, and Hashmaps are limited to homogeneous fields.
Upvotes: 1
Views: 3485
Reputation: 20542
You can use hashmap anyway.
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
All works fine
Upvotes: 2
Reputation: 2701
You can use reflection to change private fields of an object.
Say we have a Human
object, with a name
field:
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();
}
}
Like the some of the other answers suggested, you can use a HashMap<String, Object>
to store any object. You simply iterate through the map and pass the each object to the following method:
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);
}
}
}
This method retrieve all fields of the object and compare the field name to "name". If a field is identified, it will change accessibility (in case of private fields) and change the field value to newName
.
Human me = new Human("Ian");
System.out.println(me);
changeName(me, "Jan");
System.out.println(me);
Output:
Name: Ian
Name: Jan
Upvotes: 1
Reputation: 831
In addition to @dotvav comment, take a look at Apache Commons BeanUtils, which simplifies working with reflection.
Example:
Map<String, String> props = BeanUtils.describe(someObject);
if (props.containsKey("name")) {
BeanUtils.setProperty(someObject, "name", "value");
}
Upvotes: 1