为了账号安全,请及时绑定邮箱和手机立即绑定

使用流检索工资最低的员工列表

使用流检索工资最低的员工列表

拉莫斯之舞 2023-07-28 09:43:02
我正在尝试从员工列表中检索工资最低的人员列表。到目前为止,我已经设法找到工资最低的员工,但如果多个员工的工资相同,我想检索多个员工。我认为解决方案应该在一行中。因此,我无法创建一个具有最低工资的变量,而只需检查每个变量是否为“工资小于或等于 Low_Salary”。我尝试了这个,并且成功了。所以我相信我的问题是“.min(comparator)”只检索最低的之一。Comparator<Employee> comparator = Comparator.comparing( Employee :: getSalary);List<Employee> lowSalary = employees.stream()               .min(comparator)               .stream()               .collect(Collectors.toList());lowSalary.forEach(System.out::println);
查看完整描述

4 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

首先创建一个TreeMap,其键是工资。TreeMap按其键对其条目进行排序。然后获取第一个条目,即工资最低的条目,并获取与之相关的值。该解决方案仅迭代列表一次。它看起来是这样的。

List<Employee> empsWithLowestSalary = employees.stream()
    .collect(Collectors.groupingBy(Employee::getSalary, TreeMap::new, Collectors.toList()))
    .firstEntry()
    .getValue();

TreeMap将地图元素存储在红黑树中。红黑树中一个元素的插入成本为O(Log (n))。由于我们要插入n元素,因此该解决方案的总时间复杂度为O(n Log (n))。对于firstEntry(),它需要恒定的时间O(1),因为它分别维护一个指向树中最左边和最右边叶节点的指针。最左边的节点代表树中的最小值,而最右边的叶节点代表树中的最高值。

我想到编写一个服务于我们目的的自定义收集器。该收集器仅对 List 进行迭代一次,其运行时复杂度为 O(n),这明显优于上述方法。此外,它允许您在一条语句中编写客户端代码。它看起来是这样的。

static <T> Collector<T, ?, List<T>> minList(Comparator<? super T> comp) {

    return Collector.of(ArrayList::new, (list, t) -> {

        int c;

        if (list.isEmpty() || (c = comp.compare(t, list.get(0))) == 0)

            list.add(t);

        else if (c < 0) {

            /*

             * We have found a smaller element than what we already have. Clear the list and

             * add this smallest element to it.

             */

            list.clear();

            list.add(t);

        }

    }, (list1, list2) -> {

        if (comp.compare(list1.get(0), list2.get(0)) < 0)

            return list1;

        else if (comp.compare(list1.get(0), list2.get(0)) > 0)

            return list2;

        else {

            list1.addAll(list2);

            return list1;

        }

    });

}

这是您的客户端代码。


Collection<Employee> empsWithLowestSalary = employees.stream()

                .collect(minList(Comparator.comparing(Employee::getSalary)));


查看完整回答
反对 回复 2023-07-28
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

Integer lowestSalary = employees.stream()
.min(Comparator.comparing(Employee::getSalary))
.map(Employee::getSalary).get();

List<Employee> employeesWithLowestSalary = employees.stream()
.filter(e -> e.getSalary() == lowestSalary)
.collect(Collectors.toList());

首先查找最低工资是多少,然后过滤员工列表,以便只包含工资匹配的员工。


查看完整回答
反对 回复 2023-07-28
?
不负相思意

TA贡献1777条经验 获得超10个赞

您可以按工资分组,然后检索最低工资的员工列表:


List<Employee> employees = new ArrayList<Employee>(){{

    add(new Employee("bilbo baggins", 10));

    add(new Employee("frodo baggins", 10));

    add(new Employee("gandalf grey", 100));

}};


Map<Integer, List<Employee>> result = employees.stream().collect(groupingBy(Employee::getSalary));


List<Employee> allMin = result.entrySet().stream()

        .min(Comparator.comparing(Map.Entry::getKey))

        .map(Map.Entry::getValue)

        .orElse(Collections.emptyList());


allMin.forEach(System.out::println);

输出


Employee{name='bilbo baggins', salary=10}

Employee{name='frodo baggins', salary=10}


查看完整回答
反对 回复 2023-07-28
?
慕村9548890

TA贡献1884条经验 获得超4个赞

您可以先计算最低工资,然后根据您的情况使用Stream#filter:


int salary = 

   employees.stream()

            .min(Comparator.comparing(Employee::getSalary))

            .map(e -> e.getSalary())

            .orElse(-1);


List<Employee> emps = 

  employees.stream()

           .filter(emp -> emp.getSalary() == salary)

           .collect(Collectors.toList());


查看完整回答
反对 回复 2023-07-28
  • 4 回答
  • 0 关注
  • 174 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信