使用自定义密钥的Java收集分组

发布于 2025-01-23 22:09:33 字数 843 浏览 0 评论 0原文

我有一个学生的列表studentList,我想根据他们的班级和部分将它们分开,并将其分为map< customkey,list< student>>>

class Student {
public String Name;
public String Class;
public String Section;
}

我有一个自定义的密钥类,

class CustomKey {
public String Class;
public String Section;
}

我正在尝试使用此功能将它们分组,但是我们可以清楚地看到我做错了什么。

studentList.stream().collect(Collectors.groupingBy(x -> new CustomKey(x.Class, x.Section)));

组内的表达式不正确。 不允许扩展学生班:(

我想创建此输出,

{
    {"ClassA", "SectionA"}: [{name, class, section}, {name, class, section}],
    {"ClassA", "SectionB"}: [{name, class, section}],
    {"ClassB", "SectionA"}: [{name, class, section}, {name, class, section}],
}

我的知识在Java上非常有限。任何帮助/指示都受到欢迎。 另外,对于混乱的案件表示歉意。

I have a list of students studentList and i want to seperate them based on their class and section into a Map<CustomKey, List<Student>>.

class Student {
public String Name;
public String Class;
public String Section;
}

I have a custom Key Class

class CustomKey {
public String Class;
public String Section;
}

I'm trying to group them using this, but we can clearly see what I'm doing wrong.

studentList.stream().collect(Collectors.groupingBy(x -> new CustomKey(x.Class, x.Section)));

The expression inside groupingBy is incorrect.
Extending the Student Class is not allowed :(

I want to create this output

{
    {"ClassA", "SectionA"}: [{name, class, section}, {name, class, section}],
    {"ClassA", "SectionB"}: [{name, class, section}],
    {"ClassB", "SectionA"}: [{name, class, section}, {name, class, section}],
}

My knowledge is very limited on JAVA. And any help/pointers are welcomed.
Also, Apologies for the messed-up cases.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

灵芸 2025-01-30 22:09:33

好吧,customKey与其equals方法匹配,而您没有被覆盖。如果您实现等于(以及hashcode),则它将起作用。

更好的是,为CustomKey创建 record

public record CustomKey(String className, String section) { }

这将使编译器自动生成其等于 equals 和hashcode < /code>免费实现,以及getters canonical构造函数toString方法。上述记录定义等同于此:

public final class CustomKey {

    private final String className;
    private final String section;

    public CustomKey(String className, String section) {
        this.className = className;
        this.section = section;
    }

    public String className() {
        return className;
    }

    public String section() {
        return section;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof CustomKey ck
            && Objects.equals(className, ck.className)
            && Objects.equals(section, ck.section);
    }

    @Override
    public int hashCode() {
        return Objects.hash(className, section);
    }

    @Override
    public String toString() {
        return "CustomKey[className=" + className + ", section=" + section + "]";
    }
}

Well, CustomKey is matched by its equals method, which you don't have overridden. If you implement equals (and also hashCode) properly, then it'll work.

What's even better, is to create a record for CustomKey:

public record CustomKey(String className, String section) { }

This'll let the compiler auto-generate its equals and hashCode implementations for free, as well as getters, the canonical constructor and the toString method. The above record definition is equivalent to this:

public final class CustomKey {

    private final String className;
    private final String section;

    public CustomKey(String className, String section) {
        this.className = className;
        this.section = section;
    }

    public String className() {
        return className;
    }

    public String section() {
        return section;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof CustomKey ck
            && Objects.equals(className, ck.className)
            && Objects.equals(section, ck.section);
    }

    @Override
    public int hashCode() {
        return Objects.hash(className, section);
    }

    @Override
    public String toString() {
        return "CustomKey[className=" + className + ", section=" + section + "]";
    }
}
叫嚣ゝ 2025-01-30 22:09:33

我完全像下面一样使用您的代码,它对我有用,

 public void testCustomGroupBy(){
    List<Student> studentList = new ArrayList<>();
    studentList.add(new Student("name_1","class_1","section_1"));
    studentList.add(new Student("name_2","class_1","section_1"));
    studentList.add(new Student("name_3","class_2","section_1"));
    studentList.add(new Student("name_4","class_2","section_2"));
    studentList.add(new Student("name_5","class_2","section_2"));
    Map<CustomKey, List<Student>> studentsBySection = studentList.stream().collect(Collectors.groupingBy(x -> new CustomKey(x.getClassName(), x.getSection())));
    studentsBySection.entrySet().forEach(System.out::print);
}

例如下面创建您的pojo

class Student {
public String name;
public String className;
public String section;
// getters and setters

public Student(String name, String className, String section) {
    this.name = name;
    this.className = className;
    this.section = section;
}

}}

class CustomKey {
public String className;
public String section;
// getters and setters

public CustomKey(String className, String section) {
    this.className = className;
    this.section = section;
}

}

output

CustomKey(className=class_2, section=section_2)=[Student(name=name_4, className=class_2, section=section_2), Student(name=name_5, className=class_2, section=section_2)]
CustomKey(className=class_2, section=section_1)=[Student(name=name_3, className=class_2, section=section_1)]
CustomKey(className=class_1, section=section_1)=[Student(name=name_1, className=class_1, section=section_1), Student(name=name_2, className=class_1, section=section_1)]

i used your code exactly like below and it works for me

 public void testCustomGroupBy(){
    List<Student> studentList = new ArrayList<>();
    studentList.add(new Student("name_1","class_1","section_1"));
    studentList.add(new Student("name_2","class_1","section_1"));
    studentList.add(new Student("name_3","class_2","section_1"));
    studentList.add(new Student("name_4","class_2","section_2"));
    studentList.add(new Student("name_5","class_2","section_2"));
    Map<CustomKey, List<Student>> studentsBySection = studentList.stream().collect(Collectors.groupingBy(x -> new CustomKey(x.getClassName(), x.getSection())));
    studentsBySection.entrySet().forEach(System.out::print);
}

create your pojo like below

class Student {
public String name;
public String className;
public String section;
// getters and setters

public Student(String name, String className, String section) {
    this.name = name;
    this.className = className;
    this.section = section;
}

}

class CustomKey {
public String className;
public String section;
// getters and setters

public CustomKey(String className, String section) {
    this.className = className;
    this.section = section;
}

}

output

CustomKey(className=class_2, section=section_2)=[Student(name=name_4, className=class_2, section=section_2), Student(name=name_5, className=class_2, section=section_2)]
CustomKey(className=class_2, section=section_1)=[Student(name=name_3, className=class_2, section=section_1)]
CustomKey(className=class_1, section=section_1)=[Student(name=name_1, className=class_1, section=section_1), Student(name=name_2, className=class_1, section=section_1)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文