【问题标题】:Sorting and the grouping the list using Lambda使用 Lambda 对列表进行排序和分组
【发布时间】:2016-01-30 21:14:00
【问题描述】:

让我们假设我有一个员工列表:

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));
    }

现在我想要的是生成执行一些过滤的列表,例如: 薪水 > x 和薪水

到目前为止我所做的是:

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))
        );

例如:仅排序后我得到的名称::

<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>

这里有两个迈克,但现在在这两个迈克中,我想以递减的形式对他们的薪水进行排序,这样新的结果将是:

<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>

除了迈克,我不想更改其他订单

但我无法得到任何人想要的结果 请帮助我解决问题或我需要做些什么才能从这里进一步。谢谢:)

【问题讨论】:

  • 是否可以有两个具有相同薪水的迈克(假设出生年份不同)?如果是,你想如何处理它们?
  • 是的,两个员工可以同名同薪,不同dob,可以通过hashcode()管理

标签: java sorting lambda java-8 java-stream


【解决方案1】:

你可能正在寻找

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

如果您想使用降序排列,您可以根据Employee::getSalary 创建单独的Comparator comparing 并使用其reversed() 版本,例如:

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

groupingBy(Employee::getName) 的可能问题是它返回的 HashMap 是无序的。如果你想根据插入来确保键的顺序(你可能是这样,否则之前根据名称进行排序没有意义)你可以使用:

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

演示:

//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);
    }
}

输出:

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]

【讨论】:

  • 或者,您可以分组为TreeMap 并跳过排序步骤...
  • @Holger 没错,至少我们可以跳过按名称显式排序,因为 TreeMap 可以使用键的自然排序。但是我们仍然需要对列表中的值进行排序。我之前正在考虑将其添加到答案中,但决定让其他人将其作为单独的解决方案发布(所以请随意这样做)
猜你喜欢
  • 1970-01-01
  • 2020-11-11
  • 2020-12-29
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
相关资源
最近更新 更多