If I have a bean such as
public class SimpleBean
{
private String name;
private int int1;
private int int2;
private double double1;
private double double2;
// getters/setters snipped
}
what is the best way to merge two instances of the bean into one, where we only want to add the numeric values from the second bean instance to the first (i.e. we don’t care about the String ‘name’ above)
I have come up with the following solution using PropertyUtils, but am thinking it is probably not the best
public void mergeStats(Object stat)
{
try
{
Map<String, Object> beanMap = PropertyUtils.describe(stat);
// Remove ones we don't want to merge
beanMap.remove("name");
beanMap.remove("class");
for (Map.Entry<String, Object> entry:beanMap.entrySet())
{
String key = entry.getKey();
Number value = (Number) entry.getValue();
Number existingValue = (Number) PropertyUtils.getProperty(this, key);
BeanUtils.setProperty(this, key, existingValue.doubleValue() + value.doubleValue());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
Edit: I will also add that the real bean for our project contains about 100 ints & doubles, and those can change over time as business requirements change. Maintaining a function that handles each one by name is not too appealing.
Unless you’re building a framework, I’d discourage using BeanUtils, or reflection in general, for this sort of tasks. It doesn’t give you any flexibility (you still have to name yourself the fields you don’t want to include, whenever something is added to
SimpleBean).Adding properties explicitly has the advantage of being predictable and — if they become numerous — to rethink the design: perhaps arrays should be used?
Otherwise, to improve your current solution, you could check for the type of the property with
PropertyUtils.getPropertyDescriptor(...).getPropertyType(), and thus discover if it can safely be cast tojava.lang.Number, or other primitive wrapper class.