converting java hashMap to another hashMap by grouping some fields

Viewed 78

I hava a map like that(keys are customer number 1,2,3,4 etc..

Map<Long,List<Customer>> customerMap = new HashMap<Long, List<Customer>>();

public class Customer {
  private String name;
  private BigDecimal salary;

 //..getter and setters

I want to convert it to another map by grouping Name field.What i want to create map like that

Map<Long,Map<String,CustomerSalary>> convertedMap = new HashMap<Long,Map<String,CustomerSalary>>()();

public class CustomerSalary {
  private BigDecimal salary;
  private BigDecimal remainingSalary;

  //getter and setters.

What i did is

 `Map<Long,Map<String,CustomerSalary>> convertedMap =customerMap.entrySet()..stream() 
                .collect(Collectors.toMap( //collect the entries into another map
                    entry -> entry.getKey(), 
                    entry -> entry.getValue().stream()
                       .collect(groupingBy(Customer::getName,
                        reducing(BigDecimal.ZERO, Customer::getSalary, BigDecimal::add)))
                 ));

but not working because CustomerSalary should be but reducing creates BigDecimal.Do you have any idea?

Not:Salary and remainingSalary should be same initially.

2 Answers

If you're trying to sum salary, you can use the reducing() collector:

entry.getValue().stream()
        .collect(groupingBy(Customer::getName,
                reducing(BigDecimal.ZERO, Customer::getSalary, BigDecimal::add)))

If you want the result as a CustomerSalary, you can add similar operators to your class or sum and wrap via collectingAndThen().

You can try this:

Map<Long, Map<String, CustomerSalary>> collect =
    customerMap.entrySet().stream()
               .collect(toMap(e -> e.getKey(),
                              e -> e.getValue()
                                    .stream()
                                    .collect(groupingBy(Customer::getName,
                                                        collectingAndThen(reducing(BigDecimal.ZERO, Customer::getSalary, BigDecimal::add),      
                                                            s -> {                                                                                               
                                                                CustomerSalary salary = new CustomerSalary();                                                                                               
                                                                salary.setSalary(s);                                                      
                                                                salary.setRemainingSalary(s);                                                   
                                                                return salary;
                                                            })))));
Related