首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按多个值分组

按多个值分组
EN

Stack Overflow用户
提问于 2017-06-29 14:09:21
回答 2查看 1.3K关注 0票数 2

例如,我有一个学生的名单,他们的学期和科目。

代码语言:javascript
运行
复制
Subject   Semester   Attendee
---------------------------------
ITB001    1          John
ITB001    1          Bob
ITB001    1          Mickey
ITB001    2          Jenny
ITB001    2          James
MKB114    1          John
MKB114    1          Erica

当我需要用Stream api将它们按一个值分组时,我可以这样做;

代码语言:javascript
运行
复制
Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> w.getSubject()));

而且确实有用。但是,当我想按两个或多个值(如Sql句柄)对它们进行分组时,我无法确定我需要如何做。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-29 17:56:22

一种方法是按包含所有要分组的字段的类进行分组。为了按预期工作,该类必须使用所有这些字段实现hashCodeequals

在您的示例中,这将是:

代码语言:javascript
运行
复制
public class SubjectAndSemester {

    private final String subject;

    private final int semester; // an enum sounds better

    public SubjectAndSemester(String subject, int semester) {
        this.subject = subject;
        this.semester = semester;
    }

    // TODO getters and setters, hashCode and equals using both fields
}

然后,应该在Student类中创建此方法:

代码语言:javascript
运行
复制
public SubjectAndSemester bySubjectAndSemester() {
    return new SubjectAndSemester(subject, semester);
}

现在,您可以按以下方式分组:

代码语言:javascript
运行
复制
Map<SubjectAndSemester, List<Student>> studlistGrouped = studlist.stream()
    .collect(Collectors.groupingBy(Student::bySubjectAndSemester));

这将创建一个级别的学生分组。

还有一个选项不需要您使用Tuple或创建一个新的类来进行分组。我的意思是,通过使用下游groupingBy收集器,您可以对学生进行n级分组:

代码语言:javascript
运行
复制
Map<String, Map<Integer, List<Student>>> studlistGrouped = studlist.stream()
    .collect(Collectors.groupingBy(Student::getSubject,
        Collectors.groupingBy(Student::getSemester)));

这将创建一个2级分组,因此返回的结构现在是列表映射的映射。如果您可以接受这种情况,即使对更多级别进行分组,也可以避免创建充当映射键的类。

票数 1
EN

Stack Overflow用户

发布于 2017-06-29 14:16:36

您可以创建一个计算字段,该字段是两列的组合。

代码语言:javascript
运行
复制
Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> w.getSubject() + "-" w.getAttendee()));

编辑:

另一个更“适当”的解决方案:根据这篇博客文章,您需要定义一个可以容纳这两列的Tuple类:

代码语言:javascript
运行
复制
class Tuple {
    String subject;
    String attendee;
}
Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> new Tuple(w.getSubject(), w.getAttendee())));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44827524

复制
相关文章

相似问题

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