简体   繁体   中英

Sorting and the grouping the list using Lambda

lets us suppose I have a Employee list as :

private static List<Employee> list = new ArrayList<Employee>();
    static {
        list.add(new Employee("Joe", 100000, 1980));
        list.add(new Employee("Tim", 50000, 1982));
        list.add(new Employee("Mike", 90000, 1970));
        list.add(new Employee("Rick", 50000, 1955));
        list.add(new Employee("Andy", 60000, 1966));
        list.add(new Employee("Tim", 10000, 1995));
        list.add(new Employee("Tony", 130000, 1991));
        list.add(new Employee("Timmy", 150000, 1988));
        list.add(new Employee("Rich", 50000, 1980));
        list.add(new Employee("Andrew", 160000, 1970));
        list.add(new Employee("Ton", 150000, 1958));
        list.add(new Employee("Jose", 40000, 1970));
        list.add(new Employee("Timothy", 50000, 1996));
        list.add(new Employee("Ricardo", 50000, 1988));
        list.add(new Employee("Gemasio", 60000, 1971));
        list.add(new Employee("Mike", 80000, 1992));
    }

Now what i want is to generate the list which do some filtering like: salary > x and salary < y and sort according to the employee name and then again sort if multiple employee have same name but different salary but now using their salary

what I have done so far is :

System.out.println(
                list.stream()
                    .filter(e -> e.getSalary() > 55000)
                    .filter(e -> e.getSalary() < 120000)
                    .sorted(Comparator.comparing(Employee::getName))
                    .collect(Collectors.groupingBy(Employee::getName))
        );

for eg: after sorting only name i got::

<name: Andy salary: 60000 year of birth: 1966>, 
    <name: Gemasio salary: 60000 year of birth: 1971>, 
    <name: Joe salary: 100000 year of birth: 1980>, 
    <name: Mike salary: 90000 year of birth: 1970>, 
    <name: Mike salary: 80000 year of birth: 1992>

here are two mike but now Within this two Mike I want to sort their salary in decendeing form so that new result will be:

<name: Andy salary: 60000 year of birth: 1966>, 
    <name: Gemasio salary: 60000 year of birth: 1971>, 
    <name: Joe salary: 100000 year of birth: 1980>, 
    <name: Mike salary: 80000 year of birth: 1970>, 
    <name: Mike salary: 90000 year of birth: 1992>

and except Mike i dont want to change other orders

but i am not able to get the desired result will anyone please help me out what is wrong or what i need to do to further from here. Thanks :)

You are probably looking for

.sorted(Comparator
        .comparing(Employee::getName)         //sort by name
        .thenComparing(Employee::getSalary))  //in case of same names sort by salary

If you want to use descending order you can create separate Comparator which will be comparing based on Employee::getSalary and use its reversed() version like:

        .sorted(Comparator
                .comparing(Employee::getName)
                .thenComparing(
                        Comparator.comparing(Employee::getSalary).reversed()
                )
        )

Possible problem with groupingBy(Employee::getName) is that it returns HashMap which is unordered. If you want to ensure order of keys based on its insertion (and you probably are, otherwise there would be no point in sorting based on name earlier) you could use:

.collect(Collectors.groupingBy(Employee::getName, LinkedHashMap::new, Collectors.toList()));

Demo:

//code creating list
//...

//our code
Map<String, List<Employee>> grouped = list.stream()
        .filter(e -> e.getSalary() > 55000)
        .filter(e -> e.getSalary() < 120000)
        .sorted(Comparator
                .comparing(Employee::getName)
                .thenComparing(
                        Comparator.comparing(Employee::getSalary).reversed()
                )
        )
        .collect(Collectors.groupingBy(Employee::getName, LinkedHashMap::new, Collectors.toList()));

for (Map.Entry<String, List<Employee>> entry : grouped.entrySet()) {
    System.out.println(entry.getKey());
    for (Employee emp : entry.getValue()) {
        System.out.println("\t" + emp);
    }
}

Output:

Andy
    Employee [name=Andy, salary=60000, yearOfBirth=1966]
Gemasio
    Employee [name=Gemasio, salary=60000, yearOfBirth=1971]
Joe
    Employee [name=Joe, salary=100000, yearOfBirth=1980]
Mike
    Employee [name=Mike, salary=90000, yearOfBirth=1970]
    Employee [name=Mike, salary=80000, yearOfBirth=1992]

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