Java 8中String.compareIgnoreCase返回错误结果问题排查求助
问题原因分析
这个问题的核心在于Java 8中String.compareIgnoreCase的比较逻辑并非只检查字符是否是彼此的大小写版本——它是基于Unicode标准的大小写转换规则,某些看起来完全不同的字符,在转换为大写(或小写)后会变成同一个字符,从而导致比较结果返回0。
结合你的代码来看,虽然你说字符串中的"i"并非同一字符也不是大小写版本,但很可能是其中一个字符是土耳其语的无点i(ı,Unicode码点U+0131)(可能是输入错误或字体显示问题导致你看到的是"谋")。我们来拆解一下:
str1中的字符ı,经过Character.toUpperCase()转换后会变成大写的I(U+0049);str2中的普通i(U+0069),经过Character.toUpperCase()转换后也会变成I;- 两者转换后的字符完全相同,所以
compareIgnoreCase会认为这两个字符串相等,返回0。
而compareTo方法是直接比较原始字符的Unicode码点,ı和i的码点不同,所以返回非0,符合你的预期。
解决方案
如果你需要更严格的忽略大小写比较(仅允许字符是彼此的直接大小写对应,不考虑Unicode中的等价映射),可以通过以下方式实现:
手动逐个字符校验:
public static boolean strictCompareIgnoreCase(String s1, String s2) { if (s1.length() != s2.length()) { return false; } for (int i = 0; i < s1.length(); i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) { // 仅当其中一个是另一个的直接大小写版本时才视为相等 if (!(Character.toLowerCase(c1) == Character.toLowerCase(c2) && Character.toUpperCase(c1) == Character.toUpperCase(c2))) { return false; } } } return true; }使用
Collator设置严格比较强度:import java.text.Collator; public static boolean strictCollatorCompare(String s1, String s2) { Collator collator = Collator.getInstance(); // 设置比较强度为 PRIMARY,仅比较基本字符,不考虑大小写等价的非对应字符 collator.setStrength(Collator.PRIMARY); // 关闭分解模式,避免兼容等价字符的影响 collator.setDecomposition(Collator.NO_DECOMPOSITION); return collator.compare(s1, s2) == 0; }
内容的提问来源于stack exchange,提问作者Nisalon
相关产品推荐
相关产品推荐

