案例:一份问卷指派给多个学生,每个学生对该问卷进行答题,业务要求:一份问卷下有很多个问卷标题,每个标题选有很多个选项,则统计每个选项下有哪些学生选择了,统计学生id和学生姓名。
问卷原型图:
页面统计原型图:
准备工作:
eclipse4.564位 jdk1.7 64位 所需jar:fastjson-1.1.24.jar
测试代码:
package test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.google.gson.JsonObject; /** *@class:Test2 *@descript:业务要求: *1.通过问卷id查询该问卷指派了所有学生完成的文件 *2.统计该问卷下每个选项有哪些学生选择了显示学生id和学生姓名,学生人数 *@date:2016年11月9日 上午9:27:59 *@author sanghaiqin *@version:V1.0 */ public class Test2 { public static void main(String[] args) { //测试json数据 String jsonStr1="["+ "{"+ "\"identify\": \"家长\","+ "\"title\": \"家长问题1\","+ "\"type\": \"单选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": true"+ "}"+ "]"+ "},"+ "{"+ "\"identify\": \"家长\","+ "\"title\": \"家长问题2\","+ "\"type\": \"多选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": true"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": true"+ "}"+ "]"+ "},"+ "{"+ "\"identify\": \"教师\","+ "\"title\": \"教师问题1\","+ "\"type\": \"单选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": false"+ "}"+ "]"+ " },"+ "{"+ "\"identify\": \"全部\","+ "\"title\": \"家长教师问题1\","+ "\"type\": \"单选+填空\","+ "\"options\": ["+ " {"+ "\"title\": \"A\","+ "\"isanswer\": true"+ "},"+ " {"+ " \"title\": \"B\","+ "\"isanswer\": false"+ "},"+ " {"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ " {"+ "\"title\": \"D\","+ "\"isanswer\": false"+ " }"+ "]"+ " }"+ "]"; String jsonStr2="[{"+ "\"identify\": \"家长\","+ "\"title\": \"家长问题1\","+ "\"type\": \"单选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": true"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": false"+ "}"+ "]"+ "},"+ "{"+ "\"identify\": \"家长\","+ "\"title\": \"家长问题2\","+ "\"type\": \"多选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": true"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": true"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": false"+ "}"+ "]"+ "},"+ "{"+ "\"identify\": \"教师\","+ "\"title\": \"教师问题1\","+ "\"type\": \"单选\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": false"+ "}"+ "]"+ "},"+ "{"+ "\"identify\": \"全部\","+ "\"title\": \"家长教师问题1\","+ "\"type\": \"单选+填空\","+ "\"options\": ["+ "{"+ "\"title\": \"A\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"B\","+ "\"isanswer\": true"+ "},"+ "{"+ "\"title\": \"C\","+ "\"isanswer\": false"+ "},"+ "{"+ "\"title\": \"D\","+ "\"isanswer\": false"+ "}"+ "]"+ "}"+ "]"; //封装测试list集合数据 List<Map<String,Object>> dataList=new ArrayList<Map<String,Object>>(); Map<String,Object> dataMap1=new HashMap<String,Object>(); Map<String,Object> dataMap2=new HashMap<String,Object>(); dataMap1.put("studentid", 66); dataMap1.put("studentname", "李珺雯"); dataMap1.put("studentanswer", jsonStr1); dataMap2.put("studentid", 158); dataMap2.put("studentname", "瞿乐萱"); dataMap2.put("studentanswer", jsonStr2); dataList.add(dataMap1); dataList.add(dataMap2); //循环list集合数据 for(Map<String, Object> data:dataList){ String studentId=data.get("studentid").toString(); // System.out.println("studentId:"+studentId); } //封装所有满足条件数据 Map<String, Map<String, Map<String, List<StudentVo>>>> result=new HashMap<String, Map<String,Map<String,List<StudentVo>>>>(); //循环集合数据 for(Map<String, Object> dataMap:dataList){ //学生id Long studentid=Long.parseLong(dataMap.get("studentid").toString()); //学生姓名 String studentname=dataMap.get("studentname").toString(); //学生回答 JSONArray answerArray=JSONArray.parseArray(dataMap.get("studentanswer").toString()); //循环学生回答json数组 for(int i=0;i<answerArray.size();i++){ //问卷定义如:"家长","教师","全部" String identify=JSONObject.parseObject((JSONObject.toJSONString(answerArray.get(i)))).getString("identify"); //问卷类型如:"单选","多选","单选+填空" String types=JSONObject.parseObject((JSONObject.toJSONString(answerArray.get(i)))).getString("type"); //只统计问卷定义不等于教师且问卷类型为单选或者多选 if(!"教师".equals(identify) && ("单选".equals(types) || "多选".equals(types))){ //问卷标题如:"家长问题1","家长问题2" String titles=JSONObject.parseObject((JSONObject.toJSONString(answerArray.get(i)))).getString("title"); //问卷选项如:"A","B","C","D" String options=JSONObject.parseObject(JSONObject.toJSONString(answerArray.get(i))).getString("options"); //将问卷选项转换为json数组 JSONArray optionsArray=JSONArray.parseArray(options); //循环问卷选项 for(int j=0;j<optionsArray.size();j++){ //问卷选项名称 String title=JSONObject.parseObject(JSONObject.toJSONString(optionsArray.get(j))).getString("title"); //是否答题 boolean isanswer=JSONObject.parseObject(JSONObject.toJSONString(optionsArray.get(j))).getBoolean("isanswer"); //判断学生是否选中了答题,选中了则统计学生id和姓名,否则只统计每个选项标题名称 if(isanswer){ //若答题了则添加学习信息 StudentVo studentVo = new StudentVo(); studentVo.setStudentName(studentname); studentVo.setStudentId(studentid); countStudents(isanswer,titles,title,studentVo,result); }else{//未选中答题 //没有答题不需要添加学生信息 countStudents(isanswer,titles,title,null,result); } } }// end if }// end answerarray }// end datalist String resultStr=JSON.toJSONString(result, SerializerFeature.DisableCircularReferenceDetect); // System.out.println("resultStr:"+resultStr); //封装返回数据 JSONArray dataArray=new JSONArray(); JSONObject total=new JSONObject(); total.put("total", dataList.size()); dataArray.add(total); //循环得到的数据 for(Map.Entry<String, Map<String, Map<String,List<StudentVo>>>> titlesEntry:result.entrySet()){ //封装返回数据 JSONObject dataObj=new JSONObject(); //得到问卷标题如:"家长问题1","家长问题2" String titles=titlesEntry.getKey(); //封装问卷选项数据 JSONArray optionsArray=new JSONArray(); //得到问卷选项名称 Map<String, Map<String,List<StudentVo>>> titlesValue = titlesEntry.getValue(); for(Map.Entry<String, Map<String,List<StudentVo>>> titleEntry:titlesValue.entrySet()){ //封装问卷选项数据 JSONObject optionsObj=new JSONObject(); //问卷选项名称 String title=titleEntry.getKey(); //得到学生信息 Map<String,List<StudentVo>> titleValue = titleEntry.getValue(); //封装学生信息 JSONArray studentsArray=new JSONArray(); for(Map.Entry<String,List<StudentVo>> students :titleValue.entrySet()){ //得到所有学生信息 List<StudentVo> vos=students.getValue(); if(vos!=null && !vos.isEmpty()){//有数据 for(StudentVo vo:vos){ Long studentId=vo.getStudentId(); String studentName=vo.getStudentName(); JSONObject studentObj=new JSONObject(); studentObj.put("studentId", studentId); studentObj.put("studentName", studentName); studentsArray.add(studentObj); } //统计学生人数 optionsObj.put("num", studentsArray.size()); }else{//无数据 //统计学生人数 optionsObj.put("num", 0); } } //封装问卷选项 optionsObj.put("title", title); optionsObj.put("students", studentsArray); optionsArray.add(optionsObj); } //封装问卷标题 dataObj.put("title", titles); dataObj.put("options", optionsArray); dataArray.add(dataObj); } System.out.println("dataArray:"+dataArray.toString()); } /** * @descript:抽取公共方法,判断学生是否答题,若答题则添加学生信息,否则不添加,只统计选项标题名称 * @param isanswer 学生是否答题 * @param titles 问卷标题 * @param title 问卷选项标题名称 * @param result 封装满足条件结果集 */ protected static void countStudents(Boolean isanswer,String titles,String title, StudentVo studentVo,Map<String, Map<String, Map<String, List<StudentVo>>>> result){ //判断结果集是否已经包含问卷标题 if(result.containsKey(titles)){ //通过问卷标题得到问卷选项名称 Map<String, Map<String, List<StudentVo>>> titleMap=result.get(titles); if(titleMap!=null && !titleMap.isEmpty()){ //通过问卷选项名称得到学生信息 Map<String, List<StudentVo>> studentsMap=titleMap.get(title); if(studentsMap!=null && !studentsMap.isEmpty()){ //得到学生信息 List<StudentVo> studentVos=studentsMap.get("students"); //判断学生是否答题,若答题则添加学生信息,否则不添加 if(isanswer){ studentVos.add(studentVo); } //学生信息 studentsMap.put("students", studentVos); //问卷选项名称 titleMap.put(title, studentsMap); }else{//学生信息为空则创建 studentsMap=new HashMap<String, List<StudentVo>>(); //创建学生信息集合 List<StudentVo> studentVos=new ArrayList<StudentVo>(); if(isanswer){ studentVos.add(studentVo); } //学生信息 studentsMap.put("students", studentVos); //问卷选项名称 titleMap.put(title, studentsMap); } }else{//问卷选项名称为空则创建 titleMap= new HashMap<String, Map<String, List<StudentVo>>>(); Map<String, List<StudentVo>> studentsMap=new HashMap<String, List<StudentVo>>(); List<StudentVo> studentVos=new ArrayList<StudentVo>(); if(isanswer){ studentVos.add(studentVo); } //学生信息 studentsMap.put("students", studentVos); //问卷选项名称 titleMap.put(title, studentsMap); } }else{//问卷标题不存在则创建 Map<String, Map<String, List<StudentVo>>> titleMap= new HashMap<String, Map<String, List<StudentVo>>>(); Map<String, List<StudentVo>> studentsMap=new HashMap<String, List<StudentVo>>(); List<StudentVo> studentVos=new ArrayList<StudentVo>(); if(isanswer){ studentVos.add(studentVo); } //学生信息 studentsMap.put("students", studentVos); //问卷选项名称 titleMap.put(title, studentsMap); //问卷标题 result.put(titles, titleMap); } } }
上述测试代码中对测试数据进行抽取满足条件的数据resultStr效果:
{ "家长问题1": { "A": { "students": [] }, "B": { "students": [ { "studentId": 158, "studentName": "瞿乐萱" } ] }, "C": { "students": [] }, "D": { "students": [ { "studentId": 66, "studentName": "李珺雯" } ] } }, "家长问题2": { "A": { "students": [] }, "B": { "students": [ { "studentId": 66, "studentName": "李珺雯" }, { "studentId": 158, "studentName": "瞿乐萱" } ] }, "C": { "students": [ { "studentId": 158, "studentName": "瞿乐萱" } ] }, "D": { "students": [ { "studentId": 66, "studentName": "李珺雯" } ] } } }对输出满足条件的数据进行重新封装转换为json数据dataArray效果:
[ { "total": 2 }, { "options": [ { "num": 1, "students": [ { "studentId": 66, "studentName": "李珺雯" } ], "title": "D" }, { "num": 0, "students": [], "title": "A" }, { "num": 2, "students": [ { "studentId": 66, "studentName": "李珺雯" }, { "studentId": 158, "studentName": "瞿乐萱" } ], "title": "B" }, { "num": 1, "students": [ { "studentId": 158, "studentName": "瞿乐萱" } ], "title": "C" } ], "title": "家长问题2" }, { "options": [ { "num": 1, "students": [ { "studentId": 66, "studentName": "李珺雯" } ], "title": "D" }, { "num": 0, "students": [], "title": "A" }, { "num": 1, "students": [ { "studentId": 158, "studentName": "瞿乐萱" } ], "title": "B" }, { "num": 0, "students": [], "title": "C" } ], "title": "家长问题1" } ]