You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两个内容看似相同的Java ArrayList为何equals比较返回false?

排查Java字符串equals返回false的常见原因

这种情况我之前排查过好多次,肉眼看着完全一致的字符串,equals()却返回false,在你已经排除普通空格的情况下,大概率是不可见字符或编码差异在作祟,给你列几个最常见的原因和排查方法:

1. 隐藏的不可见空白字符

这是最常见的问题!很多Unicode空白字符肉眼根本分辨不出来,比如:

  • 全角空格(U+3000):看起来和半角空格一样,但编码完全不同
  • 非断空格(U+00A0):常见于网页或某些数据库导出的文本
  • 零宽空格(U+200B):完全看不见,却会占字符位置
  • 制表符(\t)、换行符(\n)、回车符(\r):有时候打印时会被忽略,但实际存在于字符串中

2. 字符串首尾的控制字符

比如空字符(\0)、Unicode控制字符(U+0000到U+001F之间的字符),这些字符在控制台输出时不会显示,但会直接影响equals()的判断。

3. 编码不一致导致的字符差异

从不同数据库加载数据时,如果两个数据库的字符编码设置不同(比如一个用GBK,一个用UTF-8),某些特殊字符可能会被解析成不同的Unicode码点,看起来一样但实际编码不同。


快速排查方法

方法一:逐个字符打印Unicode编码

写个简单的循环,对比两个字符串每个字符的编码值,一目了然:

String str1 = list1.get(1);
String str2 = list2.get(1);

// 遍历每个字符,输出字符和对应的Unicode码
for (int i = 0; i < Math.max(str1.length(), str2.length()); i++) {
    char c1 = i < str1.length() ? str1.charAt(i) : ' ';
    char c2 = i < str2.length() ? str2.charAt(i) : ' ';
    System.out.printf("位置 %d: str1='%c' (编码: %d), str2='%c' (编码: %d)%n", 
                      i, c1, (int)c1, c2, (int)c2);
}

如果某个位置的编码值不一样,那就是问题所在。

方法二:清除所有不可见字符后再比较

用正则表达式去掉所有Unicode控制字符和空白字符,再看是否相等:

String cleanedStr1 = str1.replaceAll("\\p{C}", "").replaceAll("\\p{Z}", "");
String cleanedStr2 = str2.replaceAll("\\p{C}", "").replaceAll("\\p{Z}", "");
System.out.println(cleanedStr1.equals(cleanedStr2));

如果返回true,说明原字符串里确实有不可见字符。

内容的提问来源于stack exchange,提问作者EdXX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:10:01