当前位置: 首页 > 知识库问答 >
问题:

在一起使用PartioningBy和groupingBy时无法获得所需的输出

闻人昕
2023-03-14

我正在使用收集器的groupingBy和partioningBy函数。一份工作人员名单,人员名单如下:

List<Person> persons =
        Arrays.asList(
            new Person("Max", 18),
            new Person("Peter", 23),
            new Person("Pamela", 23),
            new Person("David", 12),
            new Person("Pam", 12));

我想要的是根据名字以字母“P”开头的人来划分列表,然后根据他们的年龄来分组。下面是我的代码,它执行上述过滤:

Map<Boolean, Map<Object, List<Person>>> rr = persons.stream()
                                            .collect(Collectors.partitioningBy(p -> p.name.startsWith("P"), 
                                                    Collectors.groupingBy(p -> p.age > 20)));

我得到的输出是:

rr = {false={false=[Max, David]}, true={false=[Pam], true=[Peter, Pamela]}}

现在,我的要求是从上面的结果只得到内部map。也就是说,我要将返回值更改为:

{false=[Pam], true=[Peter, Pamela]}

也就是说,我希望partioningBy函数返回的结果(或分区映射)的布尔值为true。我怎样才能做到这一点呢?

共有1个答案

慕健
2023-03-14

您可以创建一个自定义收集器(我只做了一个练习,请将其作为练习):

 static class MyCustom<T, U> implements Collector<Person, List<Person>, Map<T, List<U>>> {

    private final Function<Person, T> function;

    private final Predicate<Person> predicate;

    private final Function<Person, U> transformingFunction;

    public MyCustom(Predicate<Person> predicate, Function<Person, T> function,
            Function<Person, U> transformingFunction) {
        this.predicate = predicate;
        this.function = function;
        this.transformingFunction = transformingFunction;
    }

    @Override
    public Supplier<List<Person>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<Person>, Person> accumulator() {
        return (list, person) -> {
            if (predicate.test(person)) {
                list.add(person);
            }
        };
    }

    @Override
    public BinaryOperator<List<Person>> combiner() {
        return (l1, l2) -> {
            l1.addAll(l2);
            return l1;
        };
    }

    @Override
    public Function<List<Person>, Map<T, List<U>>> finisher() {
        return list -> {
            return list.stream().collect(
                    Collectors.groupingBy(function, Collectors.mapping(transformingFunction, Collectors.toList())));
        };
    }

    @Override
    public Set<java.util.stream.Collector.Characteristics> characteristics() {
        return EnumSet.of(Characteristics.UNORDERED);
    }
}

然后这样应用:

 MyCustom<Integer, String> custom = new MyCustom<>((Person p) -> p.getName().startsWith("P"),
            (Person p) -> p.getAge(), Person::getName);

 System.out.println(persons.stream().collect(custom)); // {23=[Peter, Pamela], 12=[Pam]}
 类似资料:
  • 我试图创建一个程序,在这个程序中我可以接受输入,并用servlet获得一个数字的平方根。我是初学者,所以知道的不多。问题是当我尝试我的代码时,它不起作用。代码如下: myservletdemo.java 结果是:首先,当你点击链接时,你会得到: 这个结果

  • 我在使用pymongo进行mongodb聚合时遇到了< code >聚合结果超过最大文档大小(16MB)错误。 起初,我使用< code>limit()选项克服了这个问题。然而,在某个时候,我得到了 好的,我将使用 选项。当我在命令行上使用它时,此选项有效,但是当我尝试在我的 python 代码中使用时,此选项有效 我得到< code>TypeError: aggregate()正好接受2个参数(

  • 我是Spring框架的新手。我尝试在@component中使用@bean注释配置2bean。之后,我尝试getBean(按名称),得到一个NoSuchBeanDefinitionException。请帮我解决一下。 这是我的代码:-组件:

  • 我很难找到关于这些命令的功能、返回什么以及如何在C++中的应用程序中获得它们的信息。这是一个练习,这就是我需要如何获得我将从中读取的输入文件和我将向其写入的输出文件: 我试图使用: 谢谢!

  • SLF4J强制应用程序记录字符串。Log4J2 API支持记录任何CharSequence(如果您想记录文本),但也支持按原样记录任何对象。 Log4j 2 API支持日志记录消息对象、Java 8 lambda表达式和无垃圾日志记录(它在日志记录CharSequence对象时避免创建vararg数组和字符串)。

  • 我试图在谷歌中键入,并在记事本文件中获取结果的所有标题文本。我想得到所有页面上的所有可用链接,直到搜索的最后一页。但只有第一页的链接,我得到。当我调试并运行时,它可以工作大约10页。帮我做这件事。 JAVA代码: