问卷结构应解耦Question与Response,用String id标识题目,enum区分题型,ArrayList存列表;服务端校验类型、选项合法性;统计时以question.getId()为HashMap键。

问卷类结构怎么设计才方便后续统计
核心是把「问题」和「回答」解耦,用 Question 封装题干、类型、选项,用 Response 单独记录用户作答。别把答案直接塞进问题对象里——否则多人填写会互相覆盖。
-
Question用String id唯一标识,避免靠索引定位(增删题会错位) - 单选/多选用
List,不存options Map——序号只是展示用,业务逻辑不该依赖它 - 用
enum QuestionType { SINGLE_CHOICE, MULTIPLE_CHOICE, TEXT }显式区分类型,比字符串判断更安全
用 ArrayList 还是 LinkedList 存问卷列表
问卷数量通常几十到几百条,新增只在末尾,查询按 id 随机访问——ArrayList 是更优选择。用 LinkedList 反而因指针开销拖慢遍历和 get(index)。
public class Survey {
private List questions = new ArrayList<>(); // ✅ 不要用 LinkedList
private List responses = new ArrayList<>();
}
如果真要动态插题(比如跳转逻辑中插入新题),也建议用 ArrayList + add(int index, E),实测千题内性能差异可忽略。
用户提交答案时怎么校验合法性
校验必须在服务端做,前端 JS 校验仅作体验优化。关键点:类型匹配、选项存在性、必填约束。
立即学习“Java免费学习笔记(深入)”;
- 单选题提交的是
String optionId,得先用question.getOptions().contains(optionId)检查是否为合法选项值(不是序号!) - 多选题提交的是
List,需逐个检查每个optionId是否在题目选项中 - 文本题空字符串
""和null都算未填写,用StringUtils.isBlank()统一判断 - 错误直接抛
IllegalArgumentException并带具体题号,如"Q003: 选项 'X' 不存在"
统计结果时 HashMap 的 key 用什么
别用 Question 对象本身当 key——没重写 equals/hashCode 会导致统计失效。统一用 question.getId()(String)作 key,简单可靠。
Map> choiceStats = new HashMap<>(); // key 是 question.id,value 是 "选项值 → 投票数" 的映射 choiceStats.computeIfAbsent("Q001", k -> new HashMap<>()) .merge("苹果", 1, Integer::sum);
多选题统计要拆开计数:一个用户选了三个选项,就得对这三个键分别 merge(..., 1, Integer::sum),不能整个 list 当 key。
boolean skipped 标记跳过状态,比强行用集合模拟流程更实际。









