Pavan
Pavan

Reputation: 77

Efficient Way of Mapping data from Map to DTO/VO Object

I have a Map with values and i want to map this values to a DTO

Rather than using if else conditions and mapping to DTO Object , is there any better way of doing so

This is my code

public class Test {
    public static void main(String[] args) {
        HashMap<String , Object> hashMap = new HashMap<String , Object>();
        hashMap.put("empName", "Pavan");
        hashMap.put("deptNO", "12");
        hashMap.put("country", "IND");
        hashMap.put("age", "34");
        
        // TODO Auto-generated method stub
        Set<String> keys = hashMap.keySet();
        for(String key: keys){
            Employee emp = new Employee();
            if(key.equals("empName"))
            emp.setName(hashMap.get("empName"))
        }
    }
}

public class Employee {
    
    private String empName ;
    private String deptNO ;
    private String country ;
    private String age ;
    
    // setters and getters
}

I know the tradational way of doing as

for(String key: keys){
  Employee emp = new Employee();
  if(key.equals("empName"))
     emp.setName(hashMap.get("empName"))
}

Is there any better way of doing this ?

Upvotes: 0

Views: 3944

Answers (3)

Pitto
Pitto

Reputation: 8589

You can use the BeanUtils.populate to copy your HashMap keys to a bean, here's an example:

import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

public class Test {
    
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {

        HashMap<String , Object> hashMap = new HashMap<String , Object>();
        hashMap.put("empName", "Pavan");
        hashMap.put("deptNO", "12");
        hashMap.put("country", "IND");
        hashMap.put("age", "34");
        EmployeeDTO employeeDTO = new EmployeeDTO();
        BeanUtils.populate(employeeDTO,hashMap);
        System.out.println(employeeDTO);

    }

}

Output

EmployeeDTO{empName='Pavan', deptNO='12', country='IND', age='34'}

Read more here:

Upvotes: 1

Pankaj
Pankaj

Reputation: 2698

Approach using MapStruct -

Defined an interface EmployeeMapper

@Mapper
public interface EmployeeMapper {

  EmployeeMapper MAPPER = Mappers.getMapper(EmployeeMapper.class);

  @Mapping(expression = "java(parameters.get(\"empName\"))", target = "empName")
  @Mapping(expression = "java(parameters.get(\"deptNO\"))", target = "deptNO")
  @Mapping(expression = "java(parameters.get(\"country\"))", target = "country")
  @Mapping(expression = "java(parameters.get(\"age\"))", target = "age")
  Employee map(final Map<String, String> parameters);
}

and in your code call as -

Employee employee = EmployeeMapper.MAPPER.map(hashMap);

This is not as concise as you want but it does the work. Another approach is to use Qualifier, as described here. Qualifier approach is verbose and it doesn't solve your problem entirely as you still need to define mapping for each field.

MapStruct currently doesn't have full support for conversion from Map and there is a feature request and PR pending for long.

Upvotes: 0

Pramod
Pramod

Reputation: 1416

You can have a parameterized constructor for Employee class

public class Employee {
    
    private String empName;
    private String deptNO;
    private String country;
    private String age;
    
    Employee(String empName, String deptNO, String country, String age){
       this.empName = empName;
       this.deptNO = deptNO;
       this.country = country;
       this.age = age;
    }
}

and you can create Employee object from map.

public class Test {
    public static void main(String[] args) {
        HashMap<String , Object> hashMap = new HashMap<String , Object>();
        hashMap.put("empName", "Pavan");
        hashMap.put("deptNO", "12");
        hashMap.put("country", "IND");
        hashMap.put("age", "34");
        
        Employee emp = new Employee(hashMap.get("empName"), hashMap.get("deptNO"), hashMap.get("country"), hashMap.get("age"));
    }
}

EDIT: If you have many fields in map, you can use hashmap in Employee class to get the existing properties.

public class Employee {
    private HashMap<String, Object> hashMap;
    
    Employee(HashMap<String, Object> hashMap){
       this.hashMap = hashMap;
    }

    public Object getProperty(String propertyName){
       return hashMap.get(propertyName);
    }
}

Upvotes: 0

Related Questions