为什么要了解Jdk1.8,我用亲身经历告诉你

有一个同事写的一个项目,因为手上比较忙,让我临时帮忙,需要做的事情是这样的:数据库中某个字段值存的是Json字符串,这其中包含了问卷信息Json,我需要统计其中选项的累计票数,按道理而言,不是很难,但是我拿到了项目,还是有一瞬间愣神,比如该字段值的字符串如下:

[{
	"title": "您最喜欢的社团",
	"type": 0,
	"selects": [{
		"value": "轮滑社"
	}, {
		"value": "篮球协会"
	}, {
		"value": "羽毛球社"
	}, {
		"value": "辩论社"
	}],
	"selected": [1]
}, {
	"title": "长度的单位",
	"type": 1,
	"selects": [{
		"value": "m"
	}, {
		"value": "km"
	}, {
		"value": "kg"
	}, {
		"value": "cm"
	}, {
		"value": "℃"
	}, {
		"value": "㎡"
	}],
	"selected": [0, 2, 3]
}, {
	"title": "文本题-------------------------------------------------------------------------------------------------",
	"type": 2,
	"value": "测试",
	"isRequire": true
}]

其中,type为0表示单选,type为1表示多选,type为2表示文本题不统计,要做的就是统计每个选项的累计结果,比如现在有3条问卷记录,我们进行统计:

由于设计原因,也来不及更改,我的打算是先封装一个选项初始化的方法,其对应的value值(结果)初始化为0,代码如下:


public class AnswerInit {
    String title;
    String key;
    int value;

   //getter和setter略
}


/**
     * 结果集初始化
     */
    public List<AnswerInit> answerResultInit(QueAnswer que) {
        if (StringUtils.isEmpty(que.getPaperId())) {
            log.error("问卷Id为null!");
            return null;
        }
        List<QueAnswer> resultAnswer = queAnswerService.select(que);
        QueAnswer queAnswer = resultAnswer.get(0);

        /**获取作答结果 解析为Json进行选项初始化 */
        List<AnswerContentVo> answerContentVoList = null;
        try {
            answerContentVoList = JSONArray.parseArray(queAnswer.getAnswerContent(), AnswerContentVo.class);
        } catch (Exception e) {
            log.error("字符串转对象失败|失败原因=" + e.getMessage());
            return null;
        }

        List<AnswerInit> answerInits = new ArrayList<>();
        for (AnswerContentVo answerContentVo : answerContentVoList) {
            Integer type = answerContentVo.getType();
            List<Selects> selectsList = answerContentVo.getSelects();
            if (type == 2) {
                log.error("该类型不需要初始化!");
                continue;
            } else {
                for (Selects se : selectsList) {
                    AnswerInit answerInit = new AnswerInit();
                    answerInit.setTitle(answerContentVo.getTitle());
                    answerInit.setKey(se.getValue().toString());
                    answerInit.setValue(0);
                    answerInits.add(answerInit);
                }
            }
        }
        return answerInits;
    }
/** 字段值转对象 */
public class AnswerContentVo {
    private String title;

    private Integer type;

    private List<Selects> selects;

    private String[] selected;
	
	//getter和setter方法略
	
}


//controller方法如:
@RequestMapping("/ans1003")
//    @mtgLog(matterName = "答题结果统计")
    String questionAnswerCount(@RequestBody String reqStr, HttpServletRequest request) {
        QueAnswer reqVo = new InfoReqUtil().returnBean("答题结果统计", reqStr, QueAnswer.class);
        if (StringUtils.isEmpty(reqVo.getPaperId())) {
            log.error("问卷id不能为空!");
            return ResponseWrap.failure("问卷id不能为空!");
        }
        List<AnswerInit> mapInit = queAnswerService.answerResultInit(reqVo);
        log.info("计算前初始化=" + JSON.toJSONString(mapInit));
        List<QueAnswer> resultAnswer = queAnswerService.select(reqVo);
        if (resultAnswer.isEmpty()) {
            return ResponseWrap.failure("暂时没有问卷答案信息");
        } else {
            for (QueAnswer queAnswer : resultAnswer) {
                /**获取作答结果 解析为Json进行统计 统计结果返显Web */
                List<AnswerContentVo> answerContentVoList = null;
                try {
                    answerContentVoList = JSONArray.parseArray(queAnswer.getAnswerContent(), AnswerContentVo.class);
                } catch (Exception e) {
                    log.error("字符串转对象失败|失败原因=" + e.getMessage());
                    return ResponseWrap.failure("问卷答案信息非Json字符串");
                }

                for (AnswerContentVo answerContentVo : answerContentVoList) {
                    if (answerContentVo.getType() == 2) {
                        continue;
                    }
                    String title = answerContentVo.getTitle();
                    List<Selects> selectsList = answerContentVo.getSelects();
                    log.info("selected=============" + Arrays.toString(answerContentVo.getSelected()));
                    String[] selectedStr = answerContentVo.getSelected();

                    for (int i = 0; i < selectedStr.length; i++) {
//                        for (AnswerInit an : mapInit) {
                        for (int n = 0; n < mapInit.size(); n++) {
                            if (title.equals(mapInit.get(n).getTitle())) {
                                if (selectsList.get(Integer.valueOf(selectedStr[i])).getValue().equals(mapInit.get(n).getKey())) {
                                    mapInit.get(n).setValue(mapInit.get(n).getValue() + 1);
                                    mapInit.set(n, mapInit.get(n));
                                }
                            }
                        }
                    }
                }
            }
        }
        log.info("计算后结果=" + JSON.toJSONString(mapInit));
        return JSON.toJSONString(mapInit);
    }

调用方法,打印日志,验证了一下结果,满足要求,虽然结果正确,但是看源码不难发现for已经是4层嵌套:

level=ERROR|该类型不需要初始化!
计算前初始化=[{"key":"轮滑社","title":"您最喜欢的社团","value":0},{"key":"篮球协会","title":"您最喜欢的社团","value":0},{"key":"羽毛球社","title":"您最喜欢的社团","value":0},{"key":"辩论社","title":"您最喜欢的社团","value":0},{"key":"m","title":"长度的单位","value":0},{"key":"km","title":"长度的单位","value":0},{"key":"kg","title":"长度的单位","value":0},{"key":"cm","title":"长度的单位","value":0},{"key":"℃","title":"长度的单位","value":0},{"key":"㎡","title":"长度的单位","value":0}]
level=INFO|selected=============[2]
level=INFO|selected=============[1, 2, 3]
level=INFO|selected=============[0]
level=INFO|selected=============[0, 1, 3]
level=INFO|selected=============[1]
level=INFO|selected=============[0, 2, 3]
计算后结果=[{"key":"轮滑社","title":"您最喜欢的社团","value":1},{"key":"篮球协会","title":"您最喜欢的社团","value":1},{"key":"羽毛球社","title":"您最喜欢的社团","value":1},{"key":"辩论社","title":"您最喜欢的社团","value":0},{"key":"m","title":"长度的单位","value":2},{"key":"km","title":"长度的单位","value":2},{"key":"kg","title":"长度的单位","value":2},{"key":"cm","title":"长度的单位","value":3},{"key":"℃","title":"长度的单位","value":0},{"key":"㎡","title":"长度的单位","value":0}]

现在,我们更换Jdk,采用流的方式进行统计计算:


public class AnswerContentVo {
    private String title;

    private Integer type;

    private String selects;

    private String selected;

    private String dataAnalyzes;
	
	//getter和setter方法略
	
}

	@RequestMapping("/*****")
    String questionStastic(@RequestBody String reqStr, HttpServletRequest request){
        QueAnswer reqVo = new InfoReqUtil().returnBean("查看用户是否已经答题", reqStr, QueAnswer.class);
        List<QueAnswer> resultAnswer=queAnswerService.select(reqVo);
        if(resultAnswer==null || resultAnswer.size() == 0){
            return ResponseWrap.failure("暂时没有问卷答案信息");
        }else{
            
            List<List<AnswerContentVo>> ansList = resultAnswer.parallelStream()
                    .map(it -> JSONArray.parseArray(it.getAnswerContent(), AnswerContentVo.class))
                    .collect(Collectors.toList());
            List<AnswerContentVo> answerContentVos = ansList.get(0);
            // 分析数据
            answerContentVos.parallelStream().filter(o -> o.getType() != 2).forEach(o -> {
                // 已选
                List<Integer> selected = JSONArray.parseArray(o.getSelected(), Integer.class);
                // 选项
                JSONArray ans = JSONArray.parseArray(o.getSelects());
                Map<Integer, Integer> dataAnalyzes = new HashMap<>(ans.size());
                for (int i = 0; i < ans.size(); i++) {
                    dataAnalyzes.put(i, selected.contains(i) ? 1 : 0);
                }
                o.setDataAnalyzes(JSON.toJSONString(dataAnalyzes));
            });
            if (ansList.size() > 1) {
                int len = answerContentVos.size();

                IntStream.range(1, ansList.size())
                        .boxed() // 不可使用并发流
                        .forEach(o -> IntStream.range(0, len)
                                .boxed()
                                .parallel()
                                .filter(e -> answerContentVos.get(e).getType() != 2)
                                .forEach(e -> {
                                    String datas = answerContentVos.get(e).getDataAnalyzes();
                                    Map<Integer, Integer> dataAnalyzes = (Map<Integer, Integer>)JSON.parseObject(datas, Map.class);

                                    List<Integer> selectedB = JSONArray.parseArray(ansList.get(o).get(e).getSelected(), Integer.class);
                                    for (Integer s :
                                            selectedB) {
                                        dataAnalyzes.put(s, dataAnalyzes.get(s) + 1);
                                    }
                                    answerContentVos.get(e).setDataAnalyzes(JSON.toJSONString(dataAnalyzes));
                                }));
            }

            return ResponseWrap.success(JSON.toJSONString(answerContentVos));
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值