首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有可能在春季按分组分类吗?

有可能在春季按分组分类吗?
EN

Stack Overflow用户
提问于 2022-10-23 23:45:16
回答 1查看 80关注 0票数 2
代码语言:javascript
复制
List<ManualInfo> manuals = manualRepository.manuals();
manuals.stream()
    .collect(
        groupingBy( // group 1
            ManualInfo::getLargeClass,
            groupingBy( // group 2
                ManualInfo::getMediumClass,
                groupingBy( //group 3
                    ManualInfo::getSmallClass,

                )
            )
        )
    );

为了在类别结构(json)中响应手册,从数据库中检索所有手册,然后分组。分类是按照我想要的方式来安排的,但是顺序不对。

经过长时间的研究,我发现分组前的排序不起作用,分组后不能进行排序。

如下所示,我最近学习了如何按顺序分组,这也适用于类别结构吗?

代码语言:javascript
复制
LinkedHashMap<String, List<ManualInfo>> collect = manuals.stream()
                .collect(groupingBy(ManualInfo::getLargeClass, // group1
                        LinkedHashMap::new, // how can i do group2, group3....?
                        toList()));
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-24 08:05:19

如果您对列表中元素的初始顺序没有意见,那么您需要使用groupingBy()的三个args版本,它允许提供一个Supplier mapFactory来代替代码中的每个两个args分组。

这些收集器中的每一个都应该指定LinkedHashMap作为所需的积累类型:

代码语言:javascript
复制
List<ManualInfo> manuals = manualRepository.manuals();
        
var resultingMap = manuals.stream()
    .collect(Collectors.groupingBy( // group 1
        ManualInfo::getLargeClass,
        LinkedHashMap::new,
        Collectors.groupingBy( // group 2
            ManualInfo::getMediumClass,
            LinkedHashMap::new,
            Collectors.groupingBy( //group 3
                ManualInfo::getSmallClass,
                LinkedHashMap::new,
                Collectors.toList()
            )
        )
    ));

指出,必须提供一个下游集合作为带有这种风格的groupingBy()的最后一个参数,对于第一个和第二个收集器,下游将是随后的嵌套分组,而对于最后一个集合,我们需要提供作为下游的toList() (在groupingBy()的一个arg版本中隐含地使用它)。

如果数据的排序不符合您的需求,那么您需要在收集数据之前对元素进行排序。

假设ManualInfo看起来是这样的:

代码语言:javascript
复制
public class ManualInfo {
    private String largeClass;
    private String mediumClass;
    private String smallClass;
    
    // getters, constructors, etc.
}

假设您希望首先按照largeClassmediumClasssmallClass对数据进行排序。然后,使用static接口的Java8 Comparator方法,我们可以定义以下比较器(您可以使用所需的任何排序条件,这只是如何构建比较器的一个示例):

代码语言:javascript
复制
Comparator.comparing(ManualInfo::getLargeClass)
    .thenComparing(ManualInfo::getMediumClass)
    .thenComparing(ManualInfo::getSmallClass)

代码看起来可能是这样的:

代码语言:javascript
复制
var resultingMap = manuals.stream()
    .sorted( // imposing the required ordering
        Comparator.comparing(ManualInfo::getLargeClass)
            .thenComparing(ManualInfo::getMediumClass)
            .thenComparing(ManualInfo::getSmallClass)
    )
    .collect(Collectors.groupingBy( // group 1
        ManualInfo::getLargeClass,
        LinkedHashMap::new,
        Collectors.groupingBy( // group 2
            ManualInfo::getMediumClass,
            LinkedHashMap::new,
            Collectors.groupingBy( //group 3
                ManualInfo::getSmallClass,
                LinkedHashMap::new,
                Collectors.toList()
            )
        )
    ));

还有另一种选择,那就是如何强制命令。您可以使用TreeMap作为累积类型。

但是注意到,它只有在所需的排序与的分组条件完全匹配的情况下才能工作,因为TreeMap维护基于键的排序顺序。

代码语言:javascript
复制
var resultingMap = manuals.stream()
    .collect(Collectors.groupingBy( // group 1
        ManualInfo::getLargeClass,
        TreeMap::new,
        Collectors.groupingBy( // group 2
            ManualInfo::getMediumClass,
            TreeMap::new,
            Collectors.groupingBy( //group 3
                ManualInfo::getSmallClass,
                TreeMap::new,
                Collectors.toList()
            )
        )
    ));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74175553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档