案例:一份问卷指派给多个学生,每个学生对该问卷进行答题,业务要求:一份问卷下有很多个问卷标题,每个标题选有很多个选项,则统计每个选项下有哪些学生选择了,统计学生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"
}
]