gpt4 book ai didi

java - 需要来自整个组合层次结构的数据的操作模式

转载 作者:搜寻专家 更新时间:2023-10-31 01:42:33 24 4
gpt4 key购买 nike

我正在以一种“扁平化”数据的方式从合成层次结构中导出数据。因此,例如,我有 4 个类,每个类都包含层次结构中下一个类的集合:

学校数据 -> 学生数据 -> 考试记录

我想以一种扁平化的方式导出它,这样

baker elementary,dan,3/2/2001,A
baker elementary,dan,3/3/2001,B
baker elementary,dan,3/3/2001,A
baker elementary,dan,3/5/2001,C
baker elementary,kim,3/5/2001,A
baker elementary,kim,3/5/2001,B
thompson middle school,alex,1/5/2001,A

其中日期和成绩是 examrecord 的成员,学生姓名是 StudentData 的字符串成员,学校名称是 SchoolData 的字符串成员。

显然,我可以实现适当的 getter 并将所有数据提取到打印出所有内容的顶级函数调用,但我想知道是否有更优雅的方法来执行此操作。

我正在使用 C++,但语言应该不是那么重要。

最佳答案

听起来像 Visitor pattern ;从链接的维基百科条目中,访问者设计模式是一种将算法与其运行的对象结构分开的方法。

Java example from Wikipedia article

编辑 根据下面的评论,这是一个带有测试框架的完整示例。

static interface IGradeElementVisitor {
String visit(ExamRecord er);

String visit(StudentData sd);

String visit(SchoolData sd);
}

static interface IGradeElement {
void accept(IGradeElementVisitor igev);
}

static class GradeElementVisitor implements IGradeElementVisitor {

@Override
public String visit(ExamRecord er) {
StringBuilder sb = new StringBuilder();
DateFormat df = new SimpleDateFormat("M/d/yyyy");
sb.append(df.format(er.date)).append(",");
sb.append(er.grade);
return sb.toString();
}

@Override
public String visit(StudentData sd) {
StringBuilder sb = new StringBuilder();
sb.append(sd.name).append(",");
return sb.toString();
}

@Override
public String visit(SchoolData sd) {
StringBuilder sb = new StringBuilder();
for (StudentData student : sd.students) {
for (ExamRecord er : student.records) {
sb.append(sd.name);
sb.append(",");
sb.append(visit(student));
sb.append(visit(er));
sb.append(System.lineSeparator());
}
}
return sb.toString();
}

}

static class ExamRecord implements IGradeElement {
public ExamRecord(Date date, String grade) {
this.date = date;
this.grade = grade;
}

Date date;
String grade;

public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}

static class StudentData implements IGradeElement {
public StudentData(String name, List<ExamRecord> records) {
this.name = name;
this.records = records;
}

String name;
List<ExamRecord> records;

public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}

static class SchoolData implements IGradeElement {
public SchoolData(String name, List<StudentData> students) {
this.name = name;
this.students = students;
}

String name;
List<StudentData> students;

public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}

public static void main(String[] args) {
List<ExamRecord> dans = new ArrayList<>();
dans.add(new ExamRecord(new Date(2001, 2, 2), "A"));
dans.add(new ExamRecord(new Date(2001, 2, 3), "B"));
dans.add(new ExamRecord(new Date(2001, 2, 3), "A"));
dans.add(new ExamRecord(new Date(2001, 2, 5), "C"));

List<ExamRecord> kims = new ArrayList<>();
kims.add(new ExamRecord(new Date(2001, 2, 5), "A"));
kims.add(new ExamRecord(new Date(2001, 2, 5), "B"));
List<ExamRecord> alexs = new ArrayList<>();
alexs.add(new ExamRecord(new Date(2001, 0, 5), "A"));

StudentData dan = new StudentData("dan", dans);
StudentData kim = new StudentData("kim", kims);
StudentData alex = new StudentData("alex", alexs);
List<StudentData> bakers = new ArrayList<>();
bakers.add(dan);
bakers.add(kim);
List<StudentData> thompsons = new ArrayList<>();
thompsons.add(alex);
List<SchoolData> schools = new ArrayList<>();
schools.add(new SchoolData("baker elementary", bakers));
schools.add(new SchoolData("thompson middle school", thompsons));
IGradeElementVisitor visitor = new GradeElementVisitor();
for (SchoolData school : schools) {
System.out.print(visitor.visit(school));
}
}

输出是(按要求),

baker elementary,dan,3/2/3901,A
baker elementary,dan,3/3/3901,B
baker elementary,dan,3/3/3901,A
baker elementary,dan,3/5/3901,C
baker elementary,kim,3/5/3901,A
baker elementary,kim,3/5/3901,B
thompson middle school,alex,1/5/3901,A

当然,还有其他方法可以解决这个特定问题。

关于java - 需要来自整个组合层次结构的数据的操作模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26694376/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com