当前位置: 首页 > 面试题库 >

如何在Java流中对groupBy应用过滤

羊舌炯
2023-03-14
问题内容

您如何先分组然后使用Java流应用过滤?

示例 :考虑此类Employee:我想按部门分组,列出薪水大于2000的雇员。

public class Employee {
    private String department;
    private Integer salary;
    private String name;

    //getter and setter

    public Employee(String department, Integer salary, String name) {
        this.department = department;
        this.salary = salary;
        this.name = name;
    }
}

这就是我可以做到的

List<Employee> list   = new ArrayList<>();
list.add(new Employee("A", 5000, "A1"));
list.add(new Employee("B", 1000, "B1"));
list.add(new Employee("C", 6000, "C1"));
list.add(new Employee("C", 7000, "C2"));

Map<String, List<Employee>> collect = list.stream()
    .filter(e -> e.getSalary() > 2000)
    .collect(Collectors.groupingBy(Employee::getDepartment));

输出量

{A=[Employee [department=A, salary=5000, name=A1]],
 C=[Employee [department=C, salary=6000, name=C1], Employee [department=C, salary=7000, name=C2]]}

由于B部门中没有雇员的薪水高于2000。因此B部门没有密钥: 但是实际上,我想使用空列表作为密钥–

预期产量

{A=[Employee [department=A, salary=5000, name=A1]],
 B=[],
 C=[Employee [department=C, salary=6000, name=C1], Employee [department=C, salary=7000, name=C2]]}

我们应该怎么做?


问题答案:

nullpointer的答案显示了直接的方法。如果您不能更新到Java
9,没问题,那么这个filtering收集器就没有魔力。这是Java 8兼容的版本:

public static <T, A, R> Collector<T, ?, R> filtering(
    Predicate<? super T> predicate, Collector<? super T, A, R> downstream) {

    BiConsumer<A, ? super T> accumulator = downstream.accumulator();
    return Collector.of(downstream.supplier(),
        (r, t) -> { if(predicate.test(t)) accumulator.accept(r, t); },
        downstream.combiner(), downstream.finisher(),
        downstream.characteristics().toArray(new Collector.Characteristics[0]));
}

您可以将其添加到您的代码库中,并以与Java 9对应的方式相同的方式使用它,因此,如果您使用,则无需以任何方式更改代码import static



 类似资料:
  • 我有一个员工类,有薪水和部门,还有一份员工名单。 我需要找到至少有30名员工支付至少100美元工资的部门数量。 到目前为止,我已经得到了每个部门的员工数量。但是我不知道如何应用过滤器。 任何帮助都将不胜感激。

  • 我必须通过一个映射过滤对象集合,该映射包含对象字段名和字段值的键值对。我正在尝试按stream()应用所有过滤器。过滤器()。 对象实际上是JSON,因此映射包含其变量的名称以及它们必须包含的值,以便被接受,但出于简单的原因,并且由于与问题无关,我编写了一个简单的Testclass来模拟行为: 到目前为止我所尝试的: 我试着将地图的每个部分放在第一位,将集合的流放在第一位,但这两种解决方案都没有按

  • 我已经为NPE保护了第一个流,但是第二个流也可以抛出NPE,下面是代码片段: 如果getObjVal(String id)返回null,第二个流将抛出NPE。 下面的代码阻止了第二次NPE,但我觉得这不是一个好方法: 需要在另一个地方使用VAL,如果VAL不为空,将在该地方进行后续调用。有没有更好的方法来防止NPE在这里,我尝试使用可选的内部平面图,但它抛出语法错误。

  • 假设我有两个类C1和C2,其中C2由C1的构造函数使用: 现在,我有一个C2对象的列表(List list),我想使用从流式传输的C2对象创建的C1的getProperty()上的条件进行流和筛选。 有办法用溪流做到这一点吗? 我想我应该有XXXX,它使用流中的C2对象创建C1对象,并比较其getProperty()(例如,"value". equals(o2.get)) 这有可能吗?

  • 现在我有一个列表: 我想得到一个字符串列表,即从map中匹配键值的值,在' pick '列表中找到。所以,我期望得到结果{"f "," a"}。有没有办法用java stream api优雅地做到? 当有一个值时,我会这样做: 但是,当有一个键/选择列表要过滤时,就很难了。

  • 我试图重构旧代码以使用流,我的第一个方法是: 这不是编译,因为new Image()和Images.write()抛出IOExceptions。 用UncheckedIOException包装这些异常不会起作用,因为如果其中一个图像失败,我不想停止处理其他图像。 所以我结束了写2个私人方法: createImage()返回一个可选值,因为这看起来很明智。然而在此之后,我的代码变得非常丑陋: 有没有