list的主键转为数组String[]

本文介绍了一个使用 Java Stream API 的实例,展示了如何从对象列表中提取 ID 并转换为字符串数组的过程。此示例适用于熟悉 Java 编程并希望了解 Stream API 应用场景的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List<String> idList= list.stream().map(A::getId).collect(Collectors.toList());
String[] isd= idList.toArray(new String[idList.size()]);
数据库表结构题目{“A”: “1”, “B”: “2”, “C”: “3”, “D”: “5”},答案B字符串,后端/** 提交考试信息 @param examineeId @param answers @return */ public wxw_exam_record submitExam(Integer examineeId, Map<Integer, String> answers) { List<exam_question> allQuestions = exam_questionMapper.selectAll(); BigDecimal totalScore = BigDecimal.ZERO; // 更精确的分数计算 for (exam_question q : allQuestions) { String userAnswer = Optional.ofNullable(answers.get(q.getId())).orElse(“”); boolean isCorrect = checkAnswer(q.getCorrect_answer(), userAnswer); if(isCorrect) { totalScore = totalScore.add(q.getScore()); } } wxw_exam_record record = new wxw_exam_record(); record.setExamineeId(String.valueOf(examineeId)); record.setTotal_score(totalScore.doubleValue()); record.setExam_time(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); wxwExamRecordMapper.insert(record); return record; } private boolean checkAnswer(String correctAnswer, String userAnswer) { Set<String> correctSet = parseAnswer(correctAnswer); Set<String> userSet = parseAnswer(userAnswer); return correctSet.equals(userSet); } private Set<String> parseAnswer(String answer) { return Arrays.stream(answer.split(“,”)) .map(String::trim) .filter(s -> !s.isEmpty()) .collect(Collectors.toSet()); }即使选对的,也不会加分,逻辑有错误,前端的参数{examineeId: 10009, answers: {1: “B”, 2: “B”, 3: “B”}},数据库表-- wxw_demo.wxw_exam_question definition CREATE TABLE wxw_exam_question ( id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键ID’, question_type tinyint(1) NOT NULL COMMENT ‘题型(1-单选 2-多选)’, content varchar(500) NOT NULL COMMENT ‘题目内容’, options json NOT NULL COMMENT ‘选项(JSON数组格式)’, correct_answer varchar(500) NOT NULL COMMENT ‘正确答案(JSON数组)’, score decimal(5,2) NOT NULL COMMENT ‘题目分值’, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT=‘考题表options 格式’[“A. 2”, “B. 3”, “C. 4”, “D. 5”],答案[“A”],你帮我看看重新优化sql,是不是sql的数据有错误,导致匹配不成功
最新发布
03-19
<think>好的,我现在要解决用户的问题。用户提到他们的Java代码在处理考试题目评分时,即使答案选对了也不会加分。前端传的参数是{examineeId: 10009, answers: {1: “B”, 2: “B”, 3: “B”}},而数据库中的题目答案可能有问题。用户怀疑是SQL数据错误导致匹配失败,需要我帮忙检查并优化SQL。 首先,我需要理解整个流程。后端代码中,submitExam方法会查询所有考题,然后遍历每个问题,检查用户的答案是否正确。如果正确,就累加分数。关键在于checkAnswer方法,它比较正确答案和用户答案的集合是否相等。而parseAnswer方法会将答案字符串按逗号分割,去空格并转为集合。 接下来,我需要查看数据库表结构。用户提供的wxw_exam_question表结构显示correct_answer字段是varchar(500),存储的是JSON数组,比如正确答案是["A"]。而用户的前端提交的答案格式是“B”这样的字符串。例如,题目1的正确答案在数据库里是["A"],而用户提交的是“B”,这时候确实不正确,所以不加分是正确的。但如果用户提交的答案应该正确的情况却没有加分,那问题出在哪里? 可能的问题点有几个: 1. 数据库中的correct_answer存储的格式是否正确。例如,题目1的正确答案是否是["A"],但用户提交的是“A”,那么parseAnswer后,correctSet是{"A"},userSet也是{"A"},应该匹配。但如果correct_answer存储的是类似"[\"A\"]"这样的带转义字符的字符串,或者格式不正确,可能会导致split后的结果不对。 2. checkAnswer方法是否正确处理了答案。例如,如果correct_answer是JSON数组,但代码中没有正确解析,而是直接按逗号分割,可能会导致问题。比如,如果correct_answer是"[\"A\",\"B\"]",用split(",")的话会得到["[\\"A\\"", "\\"B\\"]"]这样的错误结果,导致集合不匹配。 3. 数据库中的correct_answer字段是否存储的是选项的值还是选项的标识。例如,题目选项中选项B的值是“3”,而correct_answer存储的是“B”,这时候可能需要比较的是选项的标识,而不是值,但用户提交的是“B”,所以应该没问题。 现在,用户提到前端参数中的answers是{1: “B”, 2: “B”, 3: “B”},而数据库中的correct_answer是否正确?比如,题目1的correct_answer是否是["B"]?如果是,用户提交的“B”应该正确,但实际是否被正确处理? 需要检查数据库中的数据。例如,假设题目1的correct_answer存储的是["A"],而用户提交了“B”,自然不匹配。但如果题目1的正确答案应该是B,而数据库里存的是["A"],那就是数据错误。 用户提供的表结构示例中,options字段是JSON数组,如["A. 2", "B. 3", "C. 4", "D. 5"],而correct_answer是["A"]。这可能意味着正确答案是选项A,即“2”。但用户提交的是“B”,所以如果题目1的正确答案是A,用户回答B当然错误,所以不加分是正确的。但用户的问题描述说即使选对了也不会加分,所以可能实际情况中用户认为正确答案是B,但数据库里存的是其他值。 因此,首先需要检查数据库中的correct_answer是否正确。例如,题目1的正确答案是否应该是B,但数据库中存的是["A"],导致即使用户选了B,也被判为错误。这属于数据错误,而不是代码逻辑问题。 另外,检查代码中的parseAnswer方法是否正确处理了JSON数组格式。例如,如果correct_answer字段存储的是"["A"]",即JSON数组字符串,那么用split(",")分割是否正确?比如,字符串是"["A","B"]",split后会变成["["A", "B"]"],包含方括号和引号,导致解析错误。 例如,假设correct_answer的值是"[\"B\"]",那么使用split(",")的话,分割后的每个元素会是"[\"B\"]",然后经过trim后变成"[B]",导致集合比较失败。因为用户提交的是“B”,而correctSet会是{"[B]"},而userSet是{"B"},所以不相等。 这说明代码中的parseAnswer方法可能无法正确处理JSON数组格式的correct_answer。当前代码将答案按逗号分割,但JSON数组中的元素可能包含引号和方括号,导致split后的结果包含这些字符,从而无法正确匹配。 例如,correct_answer字段的值可能是"["B"]",存储为字符串时是"[\"B\"]",当代码执行split(",")时,会得到["[\"B\"]"],然后trim后变成"["B"]",而用户提交的是"B",所以两者不匹配。 这说明问题出在correct_answer的存储格式和解析方式不匹配。代码预期correct_answer是用逗号分隔的字符串,例如"A,B",但实际上correct_answer是JSON数组格式的字符串,例如"[\"A\",\"B\"]",导致解析后的集合不正确。 因此,问题根源在于correct_answer字段存储的是JSON数组字符串,而代码中使用split(",")来解析,导致解析错误,无法正确匹配用户答案。 解决方案是修改parseAnswer方法,使其能够正确解析JSON数组字符串。例如,将correct_answer解析为实际的JSON数组,而不是简单地用逗号分割。 例如,使用JSON解析库(如Jackson或Gson)将correct_answer字符串转换为List<String>,然后再转为Set。这样,无论correct_answer中的元素是否有引号或方括号,都能正确解析。 但当前代码中的parseAnswer方法只是简单地用逗号分割,并过滤空值。这会导致如果correct_answer是JSON数组格式,解析后的结果包含方括号和引号,无法正确匹配用户提交的答案。 因此,需要修改parseAnswer方法,使其能够正确解析JSON数组。例如: private Set<String> parseAnswer(String answer) { try { ObjectMapper mapper = new ObjectMapper(); List<String> list = mapper.readValue(answer, new TypeReference<List<String>>() {}); return new HashSet<>(list); } catch (IOException e) { return Collections.emptySet(); } } 这样,correct_answer字段中的JSON数组字符串会被正确解析为字符串列表,然后转为集合。用户提交的答案如果是逗号分隔的字符串(如"B"或"A,B"),则会被正确分割并处理。 但用户当前代码中的parseAnswer方法并没有这样做,而是直接split(","),导致JSON格式的correct_answer无法正确解析。 因此,问题的根本原因是代码中的parseAnswer方法无法正确解析数据库中的correct_answer字段(JSON数组格式),导致比较失败,即使答案正确也无法加分。 另外,用户提到的数据库中的correct_answer存储的是类似["A"]的JSON数组,而用户提交的是"B",如果该题正确答案确实是"B",但数据库中存的是["A"],则属于数据错误,需要修正数据库中的正确答案。 总结可能的问题: 1. 数据库中的correct_answer字段数据错误,正确答案与实际存储不符。 2. parseAnswer方法无法正确解析JSON数组格式的correct_answer,导致比较失败。 解决方案: 1. 检查数据库中的correct_answer是否正确,确保存储的是正确的答案选项标识(如["B"])。 2. 修改parseAnswer方法,使用JSON解析库来解析correct_answer字段,而不是简单的split(",")。 例如,对于correct_answer字段的值"[\"B\"]",使用JSON解析得到["B"],而用户提交的"B"会被解析为{"B"},此时集合相等,判断正确。 如果correct_answer是多选,比如["A","B"],用户提交"A,B",则同样会被正确解析为{"A","B"},与correctSet相等。 因此,关键修改点是将parseAnswer方法中对correct_answer的处理改为JSON解析,而对用户提交的答案,可能仍然使用逗号分割(假设用户答案格式是逗号分隔的字符串,如"A,B")。 但需要确保用户提交的answers中的答案格式与数据库中的correct_answer格式一致。例如,如果correct_answer是JSON数组,用户提交的答案是否也应该以JSON数组格式传递?但根据用户的前端参数,answers是{1: “B”},即单个选项,而多选的话可能是“A,B”。 当前代码中,用户答案的处理是正确的(用逗号分割),但数据库中的correct_answer是JSON数组字符串,需要用JSON解析而不是split。 因此,修改parseAnswer方法,使其能够处理两种不同的情况: - 对于correct_answer,使用JSON解析。 - 对于userAnswer,继续使用逗号分割。 或者,统一两者的解析方式。例如,数据库中的correct_answer存储的是逗号分隔的字符串,而不是JSON数组。但根据用户提供的表结构,correct_answer的格式是JSON数组,所以可能需要调整数据库结构或代码逻辑。 如果无法修改数据库结构(例如correct_answer必须存储为JSON数组),则必须修改代码中的解析方式。 因此,正确的做法是在parseAnswer方法中,对于correct_answer使用JSON解析,而对于userAnswer,继续使用逗号分割。 所以,修改parseAnswer方法如下: private Set<String> parseAnswer(String answer, boolean isCorrectAnswer) { if (isCorrectAnswer) { // 解析JSON数组 try { ObjectMapper mapper = new ObjectMapper(); List<String> list = mapper.readValue(answer, new TypeReference<List<String>>() {}); return new HashSet<>(list); } catch (IOException e) { return Collections.emptySet(); } } else { // 用户答案用逗号分割 return Arrays.stream(answer.split(",")) .map(String::trim) .filter(s -> !s.isEmpty()) .collect(Collectors.toSet()); } } 然后,在checkAnswer方法中: private boolean checkAnswer(String correctAnswer, String userAnswer) { Set<String> correctSet = parseAnswer(correctAnswer, true); Set<String> userSet = parseAnswer(userAnswer, false); return correctSet.equals(userSet); } 这样,correctAnswer会被正确解析为JSON数组,而userAnswer则按逗号分割处理。 但是,用户提供的当前代码中,parseAnswer方法没有区分这两种情况,导致解析错误。 因此,用户的问题可能源于correct_answer存储为JSON数组,而代码没有正确解析,导致比较失败。 另外,用户提供的数据库示例中,correct_answer是["A"],而题目选项是["A. 2", "B. 3", ...]。所以正确答案对应选项的标识(如A、B),而不是选项的值(如2、3)。因此,用户提交的答案是正确的,当correct_answer存储为["B"]时,用户回答“B”应该正确。 但如果数据库中的correct_answer存储的是选项的值而不是标识,例如正确答案是3,而correct_answer存的是["3"],那么用户提交的“B”就无法匹配,因为B对应的是3,但correct_answer存的是3,导致不匹配。不过根据题目示例,correct_answer存的是选项标识,如["A"],所以应该没问题。 总结,问题可能有两个方面: 1. 数据库中的correct_answer数据不正确,例如正确答案应为B但存成了A。 2. 代码中的parseAnswer方法无法正确解析JSON数组格式的correct_answer,导致集合比较失败。 用户需要先检查数据库中的数据是否正确,然后调整代码中的解析逻辑。 例如,检查题目ID为1的correct_answer是否是["B"],如果是["A"],那么用户回答B自然错误。但如果correct_answer正确,但解析出错,就需要修改代码。 因此,解决方案步骤: 1. 检查数据库中的correct_answer是否正确,确保正确答案对应的选项标识正确存储为JSON数组。 2. 修改parseAnswer方法,使用JSON解析来处理correct_answer字段,而不是简单的split(",")。 3. 确保用户提交的答案格式与代码解析方式一致(逗号分隔)。 如果用户发现数据库中的correct_answer确实存储正确,但代码解析错误,那么修改parseAnswer方法即可。如果数据库中的数据错误,则需修正数据。</think>让我们逐步分析问题原因和解决方案: 一、问题定位 1. 数据库验证(关键步骤) 查看题目ID=1的数据: ```sql SELECT id, correct_answer FROM wxw_exam_question WHERE id IN (1,2,3); ``` 预期正确结果应为: ``` | id | correct_answer | |----|----------------| | 1 | ["B"] | -- 假设正确答案是B | 2 | ["B"] | | 3 | ["B"] | ``` *若这里显示["A"]则需要修正数据* 2. 代码逻辑验证 当前解析JSON数组错误: ```java // 错误示例:当correct_answer = "[\"B\"]"时 Set<String> correctSet = ["[\"B\"]"] // 错误解析结果 Set<String> userSet = ["B"] // 用户答案 ``` 二、解决方案 1. 修正SQL数据(若数据错误) ```sql UPDATE wxw_exam_question SET correct_answer = '["B"]' WHERE id = 1; -- 仅示例需根据实际情况修改 ``` 2. 修改Java解析逻辑 ```java private Set<String> parseAnswer(String answer) { // 统一处理JSON格式 try { ObjectMapper mapper = new ObjectMapper(); JsonNode node = mapper.readTree(answer); ArrayNode array = (ArrayNode) node; Set<String> result = new HashSet<>(); array.forEach(e -> result.add(e.asText().trim())); return result; } catch (Exception e) { // 兼容旧格式(逗号分隔) return Arrays.stream(answer.split(",")) .map(String::trim) .filter(s -> !s.isEmpty()) .collect(Collectors.toSet()); } } ``` 三、验证流程 1. 数据库验证 ```sql -- 确认答案存储格式 SELECT id, correct_answer FROM wxw_exam_question WHERE JSON_CONTAINS(correct_answer, '"B"'); ``` 2. 代码测试用例 ```java // 测试用例 void testParseAnswer() { // JSON格式解析 assert parseAnswer("[\"B\"]").equals(Set.of("B")); // 旧格式兼容 assert parseAnswer("A,B").equals(Set.of("A", "B")); // 空值处理 assert parseAnswer("").equals(Collections.emptySet()); } ``` 四、补充建议 1. 数据库优化建议 ```sql ALTER TABLE wxw_exam_question MODIFY COLUMN correct_answer json NOT NULL COMMENT '正确答案(JSON数组)'; -- 确保字段严格遵循JSON格式 ``` 2. 代码增强建议 ```java // 添加日志定位问题 private boolean checkAnswer(String correctAnswer, String userAnswer) { Set<String> correctSet = parseAnswer(correctAnswer); Set<String> userSet = parseAnswer(userAnswer); log.debug("正确答案集合: {} -> 用户答案集合: {}", correctSet, userSet); return correctSet.equals(userSet); } ``` 通过以上修改,可以确保: 1. 数据库存储的JSON格式答案能被正确解析 2. 兼容历史数据和新数据格式 3. 精确匹配用户答案与正确答案集合
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值