Java使用栈验证JSON字符串有效性的代码问题排查
JSON验证代码问题排查
问题概述
我用Stack实现了一个JSON有效性验证的Java代码,但测试用例assertTrue(JsonValidator.isValidJSON("\"{\""), "The brackets and quotes are balanced, making this a valid JSON string")始终返回false,我认为该用例是有效的JSON字符串,需要排查问题。
原代码
public class JsonValidator { public static boolean isValidJSON(String jsonString) { Stack<Character> stack = new Stack<>(); for (char c : jsonString.toCharArray()) { switch (c) { case '{': stack.push(c); break; case '}': if (stack.isEmpty()) { return false; } Character last1 = stack.pop(); if (last1 != '{') { return false; } break; case '[': stack.push(c); break; case ']': if (stack.isEmpty()) { return false; } Character last2 = stack.pop(); if (last2 != '[') { return false; } break; case '"': if (stack.isEmpty()) { return false; } Character last3 = stack.peek(); if (last3 == '"') { stack.pop(); } else { stack.push(c); } stack.push(c); } } return stack.isEmpty(); } }
问题分析
1. 引号分支重复入栈
在case '"'的逻辑末尾,多写了一行stack.push(c);,这会导致无论前面是弹出匹配的引号还是压入新引号,最终都会再压入一次引号。比如处理第一个引号时,先压入一次,末尾再压入一次,栈里会有两个引号;处理第二个引号时,弹出一个,末尾又压入一个,栈里始终剩一个引号,最终栈无法为空,返回false。
2. 错误拒绝引号开头的JSON
代码中处理引号时,首先判断if (stack.isEmpty()) { return false; },但根据JSON规范,单独的字符串值(比如"abc")是有效的JSON,此时栈初始为空,处理第一个引号时直接返回false,逻辑错误。
3. 测试用例的有效性
你传入的测试用例"\"{\""实际对应字符串是"{(双引号包裹左大括号),这是一个合法的JSON字符串值,本身是有效的,但原代码的逻辑错误导致返回false。
修复后的代码
import java.util.Stack; public class JsonValidator { public static boolean isValidJSON(String jsonString) { Stack<Character> stack = new Stack<>(); for (char c : jsonString.toCharArray()) { switch (c) { case '{': case '[': stack.push(c); break; case '}': if (stack.isEmpty() || stack.pop() != '{') { return false; } break; case ']': if (stack.isEmpty() || stack.pop() != '[') { return false; } break; case '"': // 匹配引号:栈顶是引号则弹出,否则压入 if (!stack.isEmpty() && stack.peek() == '"') { stack.pop(); } else { stack.push(c); } break; // 其他JSON允许的字符(冒号、逗号、数字、字母等)暂不处理,不影响括号和引号的匹配逻辑 } } return stack.isEmpty(); } }
修复说明
- 移除引号分支末尾多余的
stack.push(c);,避免重复入栈 - 删除引号分支中
stack.isEmpty()就返回false的判断,允许JSON以引号开头(即单独的字符串值) - 合并
{和[的入栈逻辑,简化代码 - 简化
}和]的判断逻辑,合并空栈检查和匹配检查
内容的提问来源于stack exchange,提问作者joshua
相关产品推荐
相关产品推荐

