我们有一个程序通过检查 Student 的每个字段并计算差异来比较数千对 Students
:
class Student{
String name;
String address;
String biologyCourse;
.....
// about 100 other fields
}
和计数器 POJO 类:
class Counters{
long bothStudentsHaveName;
long onlyLeftHasName;
long onlyRightHasName;
......
// number of fields in Student * 3 (both, only left, only right)
}
我们的比较函数接受 2 个学生加上计数器对象,需要扫描字段并更新相关计数器:
public void compareStudents(Student left, Student right, Counters counters){
if (!StringUtils.isEmpty(left.name) && !StringUtils.isEmpty(right.name) ){
counters.bothStudentsHaveName++;
} else if (StringUtils.isEmpty(left.name) && !StringUtils.isEmpty(right.name)){
counters.onlyRightHasName++;
} else if (!StringUtils.isEmpty(left.name) && StringUtils.isEmpty(right.name))){
counters.onlyLeftHasName++;
}
/// and now??
}
此时,我们可以像上面那样添加 100 个以上的 if/else
三元组 - 但我们相信应该有更简单的方法来做到这一点。
Reflection
可以是一个选项,也可以是 X 维数组,但我们能否以某种方式编写代码,使比较和计数更加通用?
最佳答案
我已经用一个循环解决了你的问题。但在这里我假设所有字段的命名约定都与您的问题中描述的相同。在这里,我动态访问 Student
字段并相应地更新 Counter
字段。这是完整的解决方案:
解决方案类:
public class Solution {
public void compareStudents(Student left, Student right, Counter counter) throws Exception {
for (Field field : Student.class.getDeclaredFields()) {
Object leftValue = field.get(left);
Object rightValue = field.get(right);
String fieldName = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
if(leftValue != null && rightValue != null) {
Field counterField = Counter.class.getDeclaredField("bothStudentsHave" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
} else if (leftValue != null) {
Field counterField = Counter.class.getDeclaredField("onlyLeftHas" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
} else if (rightValue != null) {
Field counterField = Counter.class.getDeclaredField("onlyRightHas" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
}
}
}
}
学生类(class):
class Student {
String name;
String address;
String biologyCourse;
}
计数器类:
class Counter {
// name
long bothStudentsHaveName;
long onlyLeftHasName;
long onlyRightHasName;
// address
long bothStudentsHaveAddress;
long onlyLeftHasAddress;
long onlyRightHasAddress;
// biologyCourse
long bothStudentsHaveBiologyCourse;
long onlyLeftHasBiologyCourse;
long onlyRightHasBiologyCourse;
// ... and so on
@Override
public String toString() {
return "Counter{" + "\n" +
"\tbothStudentsHaveName = " + bothStudentsHaveName + "\n" +
"\t, onlyLeftHasName = " + onlyLeftHasName + "\n" +
"\t, onlyRightHasName = " + onlyRightHasName + "\n" +
"\t, bothStudentsHaveAddress = " + bothStudentsHaveAddress + "\n" +
"\t, onlyLeftHasAddress = " + onlyLeftHasAddress + "\n" +
"\t, onlyRightHasAddress = " + onlyRightHasAddress + "\n" +
"\t, bothStudentsHaveBiologyCourse = " + bothStudentsHaveBiologyCourse + "\n" +
"\t, onlyLeftHasBiologyCourse = " + onlyLeftHasBiologyCourse + "\n" +
"\t, onlyRightHasBiologyCourse = " + onlyRightHasBiologyCourse + "\n" +
'}';
}
}
测试类:
public class Tester {
public static void main(String[] args) throws Exception {
// Creating Dummy Variables
Student student1 = new Student();
student1.name = "Test";
student1.biologyCourse = "Yes";
Student student2 = new Student();
student2.name = "Test1";
student2.address = "abc street";
Counter counter = new Counter();
// Comparing Students
Solution solution = new Solution();
solution.compareStudents(student1, student2, counter);
// Printing Counter
System.out.println(counter);
}
}
Output:
Counter{ bothStudentsHaveName = 1 , onlyLeftHasName = 0 , onlyRightHasName = 0 , bothStudentsHaveAddress = 0 , onlyLeftHasAddress = 0 , onlyRightHasAddress = 1 , bothStudentsHaveBiologyCourse = 0 , onlyLeftHasBiologyCourse = 1 , onlyRightHasBiologyCourse = 0 }
关于java - 如何改进 2 个对象字段的繁琐比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57782515/