这更像是一个设计问题,涉及代码简单性与性能。
假设您要确保给定用户 ID 的一组值在两个系统之间是相同的。此处的示例是检查一个学生 ID 在系统 A 和系统 B 中的课程注册数量是否相同。
为此,我们创建:
List<String> studentList = new ArrayList<String>();
Set<String> sysAEnrollments = new HashSet<String>();
Set<String> sysBEnrollments = new HashSet<String>();
private Map<String, String> badEnrollList = new HashMap<String, String>();
并适当地填写它们,给定一个学生 id 列表(studentList):
studentList = getCurrentStudentList();
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.containsAll(sysBEnrollments)){
badEnrollList.put(id, getBadEnrollmentsById(id, sysAEnrollments, sysBEnrollments));
}
}
问题:方法“ getBadEnrollmentsById ”应该返回什么?
要么是具有足够含义的串联字符串,因此可以将其打印出来。或者有一个新对象,例如另一个包含课程 ID 列表的集合,可用于进一步处理但更难用于打印输出。
为了清晰和性能,是否值得彻底设计所有预期对象或用连接字符串替换其中一些?
笔记:
- 系统A优先作为权威来源
- getBadEnrollmentsById的输出应该包含所有课程并标记系统 B 中缺少的课程。
建议的解决方案:(2012-SEP-14)
编辑(2012-SEP-17):更新 Course 类以包括 hashCode 和 equals
根据 user351721 的建议,我继续对符合预期结果/要求的剩余对象进行建模。微小的改变产生了很大的不同,让我能够克服这个设计缺陷并完成实现。
修改后的集合是:
List<String> studentList = new ArrayList<String>();
Enrollment sysAEnrollments;
Enrollment sysBEnrollments;
Map<String, List<String>> badEnrollList = new HashMap<String, List<String>>();
我们填充注册:
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.getCourses().containsAll(sysBEnrollments.getCourses())){
List<String> missingCourses = getProblemEnrollmentListById(id, sysAEnrollments, sysBEnrollments);
badEnrollList.put(id, missingCourses);
}
}
因此,现在可以通过获取每个 ArrayList 并打印课程名称来从 badEnrollList 打印输出。带有 * 的课程名称意味着它在 sysB 中缺失。
Enrollment 类如下所示:
public class Enrollment {
private Set<Course> courses = new HashSet<Course>();
public void setCourses(Set<Course> courses){
this.courses = courses;
}
public Set<Course> getCourses(){
return this.courses;
}
}
Course 课程最终是这样的:
public class Course {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
// Must override hashCode() and equals()
@Override
public boolean equals(Object o){
if (o == this)
return true;
if (!(o instanceof Course))
return false;
Course c = (Course) o;
return c.id.equals(this.id) && c.name.equals(this.name);
}
@Override
public int hashCode(){
// Magic numbers as shown on Joshua Bloch's book "Effective Java" 2nd Edition, p.48
int result = 17;
result = 31 * this.id.hashCode();
result = 31 * this.name.hashCode();
return result;
}
}
这些变化可能看起来很微妙,但重要的线索是 Enrollments 不是字符串的集合,Enrollments 是 Courses 的集合,并且每个 Course 都有一个名称和一个可用性属性。它们似乎没有做太多,但通过使用它们,我定义了我正在使用的对象,并记录了这些类在未来如何被重用。