PDJ
PDJ

Reputation: 79

Group List of Object based on few variables

I have Employee table with columns dept, dept_id,floor,bonus_appl,first_nm,last_nm,salary,experience.

Equivalent Pojo looks like

class Employee{
    String department;
    String departmentId;
    int floor;
    Boolean isBonusApplicable;
    String firstName;
    String lastName;
    Long salary;
    int experience;    
}

I am able to use JDBC Template to fetch the resultset from database and create List of employees.

Now, I would like to use Stream to group all the common variables(i.e., department, department ID etc)of this class together so that my Pojo will not have the common variables repeated

{
    "department" : [
        {
            "department" : "HR",
            "departmentId" : "EMP_SECTION_1",
            "floor" : 2,
            "isBonusApplicable" : false,
            "employees": [
                {
                    "firstName" : "sunil",
                    "lastName"  : "kumar",
                    "salary"    : 100000,
                    "experience" : 10
                },
                {
                    "firstName" : "Anitha",
                    "lastName"  : "Shri",
                    "salary"    : 55000,
                    "experience" : 7
                }
            ]

        },
        {
            "department" : "Network",
            "departmentId" : "EMP_SECTION_7",
            "floor" : 1,
            "isBonusApplicable" : true,
            "employees": [
                {
                    "firstName" : "Harish",
                    "lastName"  : "Shah",
                    "salary"    : 12000,
                    "experience" : 1
                },
                {
                    "firstName" : "Vignesh",
                    "lastName"  : "Murthy",
                    "salary"    : 25000,
                    "experience" : 3
                }
            ]
        }    
    ]     
}

can someone help me how to group them together with a piece of code. Am new to stream API

List<Employee>  employeeList = dao.getEmployeeList();
System.out.println(employeeList.size());  //returns 276 employee details spanning across 7 different departments

Upvotes: 0

Views: 150

Answers (1)

Nowhere Man
Nowhere Man

Reputation: 19555

Separate POJOs have to be implemented to store department and related list of employees.

The example below uses Lombok annotations @Data and @AllArgsConstructor to indicate that appropriate getters/setters/constructors are implemented as well as methods hashCode and equals are overridden which are important for DepartmentDto to be used as a key in an intermediate map.

@Data
@AllArgsConstructor
class DepartmentDto {
    String department;
    String departmentId;
    int floor;
    Boolean isBonusApplicable; 

    List<EmployeeDto> employees;
}

@Data
@AllArgsConstructor
class EmployeeDto {
    String firstName;
    String lastName;
    Long salary;
    int experience;  
}

Then List<Employee> may be converted into List<DepartmentDto>:

List<DepartmentDto> depts = employees.stream() // Stream<Employee>
    .collect(Collectors.groupingBy(
        emp -> new DepartmentDto(
            emp.getDepartment(), emp.getDepartmentId(),
            emp.getFloor(), emp.isBonusApplicable(), null
        ), // key - DepartmentDto
        Collectors.mapping(
            emp -> new EmployeeDto(
                emp.getFirstName(), emp.getLastName(),
                emp.getSalary(), emp.getExperience()
            ),
            Collectors.toList() 
        ) // value -> List<EmployeeDto>
    ))  // Map<DepartmentDto, List<EmployeeDto>>
    .entrySet()
    .stream()
    .map(e -> new DepartmentDto( // copy and set employee list
            e.getKey().getDepartment(), e.getKey().getDepartmentId(),
            e.getKey().getFloor(), e.getKey().isBonusApplicable(),
            e.getValue()
    ))
    .collect(Collectors.toList());

Upvotes: 1

Related Questions