对 CaseInsensitiveComparator 的实现感到好奇
Curious about the implementation of CaseInsensitiveComparator
当我检查 CaseInsensitiveComparator
的实现时,它是 String
的私有内部 class,我发现了奇怪的事情。
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
...
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
}
...
}
我很好奇的是:在for
循环中,一旦比较了大写字符,为什么还要再比较小写字符?当Character.toUpperCase(c1)
和Character.toUpperCase(c2)
不同时,Character.toLowerCase(c1)
和Character.toLowerCase(c2)
是否可能相等?
难道不能简化成这样吗?
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
return n1 - n2;
}
我是不是漏掉了什么?
有些 Unicode 字符的小写形式不同,但大写形式相同。例如希腊字母 Sigma - 它有两种小写形式(σ 和 ς,仅在词尾使用),但只有一种大写形式 (Σ)。
我找不到任何反向的例子,但是如果将来发生这种情况,当前的Java实现已经为此做好了准备。您的 Comparator
版本肯定会正确处理 Sigma 案例。
您可以在 Unicode 网站的 Case Mapping FAQ 中找到更多信息。
当我检查 CaseInsensitiveComparator
的实现时,它是 String
的私有内部 class,我发现了奇怪的事情。
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
...
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
}
...
}
我很好奇的是:在for
循环中,一旦比较了大写字符,为什么还要再比较小写字符?当Character.toUpperCase(c1)
和Character.toUpperCase(c2)
不同时,Character.toLowerCase(c1)
和Character.toLowerCase(c2)
是否可能相等?
难道不能简化成这样吗?
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
return n1 - n2;
}
我是不是漏掉了什么?
有些 Unicode 字符的小写形式不同,但大写形式相同。例如希腊字母 Sigma - 它有两种小写形式(σ 和 ς,仅在词尾使用),但只有一种大写形式 (Σ)。
我找不到任何反向的例子,但是如果将来发生这种情况,当前的Java实现已经为此做好了准备。您的 Comparator
版本肯定会正确处理 Sigma 案例。
您可以在 Unicode 网站的 Case Mapping FAQ 中找到更多信息。