UTF-8格式CSV文件字符串与ArrayList中字符串匹配失败问题
嘿,这个问题我之前也碰到过,咱们一步步来拆解搞定它!
问题核心分析
首先得明确:控制台显示的问号大多是编码渲染问题,不代表字符本身是问号;但JUnit断言失败,说明两个字符串的实际Unicode码点肯定不一样——这才是关键!
1. 先搞清楚两个字符串的真实面目
别被控制台的表象骗了,直接打印对应字符的Unicode编码,就能瞬间定位问题:
// 假设strList是你ArrayList里的字符串,strTarget是要比较的那个“显示为问号”的字符串 char midInList = strList.get(0).charAt(你的间隔号位置); char midInTarget = strTarget.charAt(你的间隔号位置); System.out.printf("ArrayList里的间隔号Unicode: U+%04X%n", (int) midInList); System.out.printf("待比较字符串的间隔号Unicode: U+%04X%n", (int) midInTarget);
- 如果两个输出都是
U+00B7:那控制台显示问号只是终端编码没设对(比如默认用了GBK),但字符本身是对的,断言失败大概率是字符串藏了空格、换行这类不可见字符。 - 如果一个是
U+00B7,另一个是U+003F:那说明你读取待比较字符串时没指定UTF-8编码,比如用了系统默认编码(Windows下是GBK)读取UTF-8的CSV,直接把间隔号转成了问号。
2. 检查你的读取逻辑(针对ArrayList的代码)
你现在用InputStreamReader(inputStream, StandardCharsets.UTF_8)读取的方式是对的,但要确认两件事:
- 你的CSV文件确实是纯UTF-8编码:有些编辑器保存时会偷偷加BOM(字节顺序标记),或者存成了UTF-16,这会导致读取异常。可以用Notepad++打开文件,查看编码是不是“UTF-8无BOM”。
- 所有读取操作都显式指定UTF-8:别依赖系统默认编码,不管读什么文件,都加上
StandardCharsets.UTF_8参数,避免环境差异坑你。
3. JUnit断言的优化技巧
如果确认字符都是正确的U+00B7,但断言还是失败,别用assertTrue(str1.equals(str2)),换成assertEquals——它会在失败时输出两个字符串的具体内容,帮你快速找到差异:
assertEquals("两个字符串应该完全相等", strFromList, strToCompare);
另外,排查下有没有不可见字符:打印两个字符串的长度,或者用trim()去掉前后空格再试试:
System.out.println("ArrayList字符串长度: " + strFromList.length()); System.out.println("待比较字符串长度: " + strToCompare.length());
4. 修复控制台显示(可选)
如果只是想让控制台正常显示间隔号,设置终端编码为UTF-8就行:
- IDEA中:
File > Settings > Editor > General > Console,把Console Encoding改成UTF-8。 - Windows命令行:执行
chcp 65001切换编码;Linux/macOS则设置export LANG=en_US.UTF-8。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

