使用多个过滤器进行分组并使用过滤器名称作为输出映射中的键

问题描述 投票:0回答:1

假设我有 3 个或 n 个过滤器。就说3吧。 假设我定义了这些过滤器并创建了它的地图

class Person {
      Strong status;
}

Predicate<Person> completedP = j->j.getStatus().equalsIgnoreCase("completed");
Predicate<Person> inProgressP = j->j.getStatus().equalsIgnoreCase("inprogress");
Predicate<Person> nullStatusP = j->j.getStatus() == null && j.id() == null;

Map<String, Predicate<Person>> filterMap =  Map.of("complatedP",completedP, 
"inProgressP", inProgressP, "nullStatusP", nullStatusP);

现在假设我的输入为

List<Person> people
我如何获得输出/结果
Map<String, List<Person>>

考虑以下示例数据

        Person p1 = new Person("completedP");
        Person p2 = new Person("completedP");
                
        Person p3 = new Person("inProgressP");
        Person p4 = new Person("inProgressP");
        
        Person p5 = new Person(null);
        Person p6 = new Person(null);

我想要的结果是:

completedP
键有
p1,p2

inProgressP
键有
p3,p4

nullStatusP
键有
p5,p6

结果映射的关键是 3 个过滤器名称之一。我不想做 groupBy 3 次并每次应用单个过滤器。 如果地图中有

N
过滤器,我该如何概括。对于我目前的要求,3 个过滤器就足够了

java java-8
1个回答
0
投票

您可以编写一个辅助方法,根据过滤器的

Map
Person
,告诉您分组的关键。

private static String group(Map<String, Predicate<Person>> filters, Person person) {
    return filters.entrySet().stream()
            .filter(x -> x.getValue().test(person))
            .map(Map.Entry::getKey)
            .findAny().orElseThrow();
}

这假设每个

Person
恰好匹配一个过滤器,如果
Person
不匹配任何过滤器,则会抛出异常。您可以将
orElseThrow
更改为
orElse("some other group")
以将它们放入另一组中。

然后你可以这样做:

var groups = people.stream().collect(Collectors.groupingBy(x -> group(filterMap, x)));
© www.soinside.com 2019 - 2024. All rights reserved.