rushabh sojitra
rushabh sojitra

Reputation: 152

Dynamic Grouping using groupby() in java

I am working on some scenario.

where the user selects some columns and the grouping on them is done and displayed.

I have done using criteria and now I want to use java groupby() to group.

Consider I have an entity Employee:

package com.demo;

public class Employee {
    
    int id;
    String name;
    String address;
    String phoneno;
    String designation;
    
    
    public Employee(int id, String name, String address, String phoneno, String designation) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.phoneno = phoneno;
        this.designation = designation;
    }
}

// getter and setters

I have created another class for grouping

public class GroupHere {
    public static void main(String arg[]) {

Function<Employee, List<Object>> classifier = (emp) ->
        Arrays.<Object>asList(emp.getAddress(),emp.getName());

Map<Employee, Long> groupedEmployee = employee.stream()
                  .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

System.out.println("key" + groupedEmployee .keySet());
System.out.println("Grouped by" + groupedEmployee );

   }
}
        

Now I wanted to dynamically create my classifier so when the user selects '''name''' and '''phoneno''' the classifier should have these getters in it.

I am confused here.

Also when user selects the attributes/column that details is in JSON.

{
 [ attributes: name, groupable: true ],
 [ attributes: phoneno, groupable: true ]
}

How can I map the attributes with the getters of Employee and add into classifier ?

Or is their any other way to group this attributes?

Upvotes: 2

Views: 820

Answers (1)

fps
fps

Reputation: 34460

You could do it by using a map from attribute names to attribute extractors, i.e:

Map<String, Function<Employee, Object>> extractors = new HashMap<>();
extractors.put("name", Employee::getName);
extractors.put("address", Employee::getAddress);
extractors.put("phoneno", Employee::getPhoneno);
extractors.put("designation", Employee::getDesignation);

Once you have this map, you can use it to create your classifier dynamically:

List<String> attributes = ...; // get attributes from JSON (left as exercise)

Function<Employee, List<Object>> classifier = emp -> attributes.stream()
    .map(attr -> extractors.get(attr).apply(emp))
    .collect(Collectors.toList());

Now, you can use this classifier to gruop the employees:

Map<List<Object>, Long> groupedEmployees = employees.stream()
    .collect(Collectors.groupingBy(classifier, Collectors.counting()));

Upvotes: 4

Related Questions