简体   繁体   中英

How to sort Employee object based on salary,name in ascending order from Map<String, Map<String, ArrayList<Employee>>>using Java8 streams API

Map<String, Map<String, ArrayList<Employee>>> map = new HashMap<String, Map<String, ArrayList<Employee>>>();
ArrayList<Employee> list = new ArrayList<Employee>();
Map<String, ArrayList<Employee>> empMap = new HashMap<>();

Employee e1 = new Employee("Raju", 10000);
Employee e2 = new Employee("Naresh", 2000);
Employee e3 = new Employee("Sugg", 30000);
Employee e4 = new Employee("Asd", 30000);
list.add(e1);
list.add(e2);
list.add(e3);
list.add(e4);
empMap.put("w1", list);

map.put("t1", empMap);

Comparator<Employee> cmp = (i1, i2) -> i1.getSal().compareTo(i2.getSal());
Comparator<Employee> cmp1 = (i1, i2) -> i1.getName().compareTo(i2.getName());

map.values().stream().map(m -> {
    return m.values().stream().map(l -> {
        l.sort(cmp.thenComparing(cmp1));
        return l;
    });
}).flatMap(m -> m).forEach(l -> {
    l.forEach(l1 -> System.out.println(l1.getName() + " " + l1.getSal()));
});

Map is the main object, empMap is the map inside main map, list is the list of Employee objets. I tried the sorting in above but Is any other way above code can be optimized?

If you want to just sort the ArrayList<Employee> inside the Map you can use forEach to iterate the map and use sort method on ArrayList

 map.forEach((key,value)->{
        value.forEach((nKey,nValue)->{
            nValue.sort(Comparator.comparing(Employee::getSalary).thenComparing(Employee::getName));
        });
    });

You have been created two Comparator functions - it is good way and practice, in additional you can change last part of your code - it look slightly confusing:

    map.values().stream()
            .flatMap(m -> m.values().stream())
            .forEach(l -> l.sort(cmp.thenComparing(cmp1)));

Or

map.forEach((key,value)-> 
            value.values()
            .forEach(v -> v.sort(cmp.thenComparing(cmp1))));

If you want a complete streams solution you can do it as follows. This just streams each outer out and inner in entrySets and the sorts the list based on the specified requirements. I added a duplicate name with a different salary for a complete demonstration.

Map<String, Map<String, List<Employee>>> results = map
        .entrySet().stream()
        .collect(Collectors.toMap(out -> out.getKey(),
                out -> out.getValue().entrySet().stream()
                        .collect(Collectors.toMap(
                                in -> in.getKey(),
                                in -> in.getValue().stream()
                                        .sorted(Comparator
                                                .comparing(
                                                        Employee::getName)
                                                .thenComparing(
                                                        Employee::getSalary))
                                        .collect(Collectors
                                                .toList())))));

results.entrySet().forEach(System.out::println);

Prints

t1={w1=[[Asd,  30000], [Naresh,  2000], [Naresh,  10000], [Raju,  10000], [Sugg,
  30000]]}

Of course, since the List itself is mutable it is much more straight forward to just sort the list in place as described in other answer(s) and not create a new map.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM