forker
forker

Reputation: 2679

Set object fields from HashMap

Is there a library that can do the following?:

Given an Object and a HashMap, it enumerates the keys of the Hashmap and looks up the setters for these keys in the Object and sets the associated values. Something looking like that:

public Object setData(Object object, HashMap<String, Object> fields) {
   for (Entry<String, Object> entry : fields.entrySet()) {
      Method m = object.getClass().getMethod("set" + entry.getKey(), entry.getValue().getClass());
      if (m != null) {
         m.invoke(object, entry.getValue());
      }
   }
   return object;
}

The task looks simple at the first look but there are some nuances that I hope someone has already taken care of. As you know, reinventing the wheel (the good wheel) is a bad approach.

Upvotes: 21

Views: 26830

Answers (5)

Jerome L
Jerome L

Reputation: 637

BeanUtils is fine.

But, as good practice, i would not write code that use reflection. Or as the last solution i have, if none other has been found.

This code cannot be tracked in IDE like Eclipse (no call hierarchy), making the developer think that the setters are never called. He can break your code and that will still compile.

Too high level of abstraction like this makes the code difficult to understand.

Code that is being obfuscated will be broken by the obfuscator itself when writting such things.

Best solution would be to rethink the use of reflection to set the object fields.

Upvotes: 3

quaylar
quaylar

Reputation: 2635

Check out http://commons.apache.org/beanutils/, in particular BeanUtils.populate():

http://commons.apache.org/beanutils/v1.8.3/apidocs/index.html

Upvotes: 0

e-zinc
e-zinc

Reputation: 4581

Look at Apache Commons BeanUtils

org.apache.commons.beanutils.BeanUtils.populate(Object bean, Map properties)

Javadoc:
Populate the JavaBeans properties of the specified bean, based on the specified name/value pairs. This method uses Java reflection APIs to identify corresponding "property setter" method names, and deals with setter arguments of type String, boolean, int, long, float, and double.

Upvotes: 22

Jesper
Jesper

Reputation: 206846

I have a BeanAsMap class that I wrote a long time ago. The method asMap returns a Map that is a view on a Java bean (POJO). You can call putAll on that Map, passing it the Map that you want to copy data from.

Feel free to use my code mentioned above.

Example:

MyClass bean = ...;
Map<String, Object> inputData = ...;

Map<String, Object> view = BeanAsMap.asMap(bean);
view.putAll(inputData);

Upvotes: 3

Wojciech Owczarczyk
Wojciech Owczarczyk

Reputation: 5735

Better use BeanUtils class:

public Object setData(Object object, HashMap<String, Object> fields) {
   for(Entry<String, Object> entry : fields.entrySet()) {
      BeanUtils.setProperty(object, entry.getKey(), entry.getValue());
   }
   return object;
}

Upvotes: 7

Related Questions