list添加集合被覆盖,利用map求和——代码应该怎么放
项目中学生各科成绩信息查询,相应拼接学生实体和课程成绩实体,拼接之后查出来的结果如下:
"list": [
{
"studentCode": "12040341008",
"studentName": "张三2",
"courseScoreList": [
{
"courseName": "测试1课",
"singleCourseScore": 50
},
{
"courseName": "测试2课",
"singleCourseScore": 50
}
],
"courseList": [
"测试1课",
"测试2课"
],
"studentTotalScore": 50,
"className": null,
"termName": null,
"professionName": null
},
{
"studentCode": "12040341008",
"studentName": "张三2",
"courseScoreList": [
{
"courseName": "测试1课",
"singleCourseScore": 50
},
{
"courseName": "测试2课",
"singleCourseScore": 50
}
],
"courseList": [
"测试1课",
"测试2课"
],
"studentTotalScore": 100,
"className": null,
"termName": null,
"professionName": null
}
],
看出有什么异常了吗?一个学号应该一个list就可以了,但是这里两个课程同一个学号便出现了两次,这个怎么办?而且如果有三个课程的话总分studentTotalScore还是100
list被覆盖:http://www.cnblogs.com/ms27946/p/4801686.html
引用类型变量的赋值只复制对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。在for循环赋值的时候,一直都在同一个对象赋值add给List集合;
——只需要把for循环外面定义的实体类转移到for循环内部就可以了,每添加一个实体对象就new一个出来保证不同
根据大神说的,相应的改了一下代码的位置(看起来只是改了位置,背后却多做了很多事情)
public List<SingleCourseScoreShowEntity> joinToSingleCoureScore(List<StudentScoreCollectEntity> studentScoreCollectEntityList, List<StudentModel> studentModelList) {
List<SingleCourseScoreShowEntity> singleCourseScoreShowEntityList = new ArrayList<>();
//存放课程名称
List<String> courseList = new ArrayList<>();
//承接拼写的字符串 存放课程的相关信息
SingleCourseScoreShowEntity studentScoreEntityForWebShow = null;
//存放学生各科成绩包括课程信息及其对应的成绩
List<ScoreManagerCouseScoreModel> scoreManagerCouseScoreModels=new ArrayList<>();
//存放学生总成绩
TreeMap<String, Integer> hashMapTotalScore = new TreeMap();
//学生实体
for (StudentModel studentModel : studentModelList) {
//region 学生课程成绩实体 studentScoreCollectEntity 一个课程为一个实例集合
for (StudentScoreCollectEntity studentScoreCollectEntityForWeb : studentScoreCollectEntityList) {
if (studentModel.getId().equals(studentScoreCollectEntityForWeb.getStudentId())) {
//承接拼写的字符串 存放课程的相关信息
studentScoreEntityForWebShow = new SingleCourseScoreShowEntity();
//存放 课程信息+对应的成绩
ScoreManagerCouseScoreModel scoreManagerCouseScoreModel =new ScoreManagerCouseScoreModel();
//region 一条课程信息实体
// 姓名
studentScoreEntityForWebShow.setStudentName(studentScoreCollectEntityForWeb.getStudentName());
//学号
studentScoreEntityForWebShow.setStudentCode(studentModel.getStudentCode());
//单个成绩总分
Integer singleScore = Integer.parseInt(studentScoreCollectEntityForWeb.getTotalScore());
//存放 课程信息+对应的成绩 list 1存放课程名称
scoreManagerCouseScoreModel.setCourseName(studentScoreCollectEntityForWeb.getCourseName());
//存放课程名称
courseList.add(studentScoreCollectEntityForWeb.getCourseName());
studentScoreEntityForWebShow.setCourseList(courseList);
//存放 课程信息+对应的成绩 list 2存放该课程的对应分数
scoreManagerCouseScoreModel.setSingleCourseScore(Integer.parseInt(studentScoreCollectEntityForWeb.getTotalScore()));
//存放到课程分数实体中
scoreManagerCouseScoreModels.add(scoreManagerCouseScoreModel);
//存放到返回值所在的实体中,返回
studentScoreEntityForWebShow.setCourseScoreList(scoreManagerCouseScoreModels);
//region 算学生总成绩
String studentId = studentScoreCollectEntityForWeb.getStudentId();
//map 中是否 存有该 学生信息
boolean jundgeStudentNum = hashMapTotalScore.containsKey(studentId);
//用于存放 总分,如果学生唯一标识存在,则说明该学生的牟科成绩已经存放,需要和已经存放的成绩相加算总分
if (jundgeStudentNum) {
hashMapTotalScore.put(studentId,hashMapTotalScore.get(studentId)+ singleScore);
//获取各科的总分
studentScoreEntityForWebShow.setStudentTotalScore(hashMapTotalScore.get(studentId));
} else {
// 不存在则该学生未在map中,添加该生的成绩
hashMapTotalScore.put(studentId, singleScore);
studentScoreEntityForWebShow.setStudentTotalScore(singleScore);
}
//endregion
//endregion
}
}
//课程实体信息 添加到 list 写在这里 一个学号是一个list(包含多条课程信息)
// 而写在上面 一个课程是一个list= 一个学生多条数据 = 冗余数据
singleCourseScoreShowEntityList.add(studentScoreEntityForWebShow);
}
return singleCourseScoreShowEntityList;
}
这里的return也做了一些改动,否则就像注释里面说的会有冗余的数据,list覆盖还有list.addAll()方法,http://www.yiibai.com/java/util/arraylist_addall.html;该方法会将所有指定集合中的元素添加到此列表的结尾,https://book.2cto.com/201309/31793.html;这个方法具体没有实践,以后再说吧
求和的思路是借助一个TreeMap,注释还可以哈,那是我要表达的意思,原来是这样写的
if (jundgeStudentNum) {
Integer totalScore = hashMapTotalScore.get(studentId) + singleScore;
//获取各科的总分
studentScoreEntityForWebShow.setStudentTotalScore(totalScore);
} else {
// 不存在则该学生未在map中,开始他的添加
hashMapTotalScore.put(studentId, singleScore);
studentScoreEntityForWebShow.setStudentTotalScore(singleScore);
}
3个50算出了是100,走了好几次单元测试,我也是醉了,后来改成上 上面的代码,150出来了而且一个学生只要一个list哦,哈哈~解决了
看到这里大家有没有想起之前学过的值引用和地址引用,最近在学c++也接触了这部分的知识,相对来说容易理解了很多:
值引用:基本数据类型都是值传递,复制对象的值,传递后就互不相关
如下图将形参i的值复制了一份给 i,执行方法体,又让i=1234,因为是局部变量方法运行完, i 消失
引用类型变量的赋值只复制对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。
形参和实参的指针指向了堆中的同一对象:对象的引用和数组的引用。
虽然是引用类型但是方法体中 new出了一个新变量,b是局部变量 方法执行完 b消失,对应的堆里面的东西等待垃圾收集器回收,new新对象不会改变原来对象的值,因为地址不一样;方法change3将d2的引用给了b,方法体调用d也就是d2的方法setDay方法,改变了d2 Day的值
值传递好比是你把文件复制一份,通过网络传给他,然后他可以在他本机上对文件做任何的修改,修改会保存下来,但是你机器上的文件不会发生任何的变化。即形参与实参是两个不同的变量,各自占用不同的存储单元。
地址传递好比是你把文件在网络上的地址告诉他人,他人通过网络访问你机器上的文件,他可以对文件进行修改并保存,此时,文件的内容就会发生变化。即形参与实参是相同的变量,占用同一段内存空间。