compareTo() 方法详解:按字典顺序比较字符串(区分大小写)

方法定义

public int compareTo(String anotherString)

功能说明

  • 字典顺序比较:基于字符的 Unicode 值逐个比较字符串
  • 区分大小写:大写字母(A-Z)小于小写字母(a-z)
  • 返回值含义
    • 负整数:当前字符串字典序小于参数字符串
    • :两字符串相等
    • 正整数:当前字符串字典序大于参数字符串
  • 比较规则
    1. 比较对应索引位置的字符 Unicode 值
    2. 遇到第一个不同字符时返回差值
    3. 若共同前缀相同,返回长度差(较短字符串在前)

示例代码

public class CompareToDemo {
    public static void main(String[] args) {
        // 相同字符串
        System.out.println("apple".compareTo("apple"));  // 0
        
        // 首字母差异
        System.out.println("apple".compareTo("banana")); // -1('a'(97) - 'b'(98))
        
        // 大小写敏感
        System.out.println("Apple".compareTo("apple")); // -32('A'(65) - 'a'(97))
        
        // 长度差异(共同前缀相同)
        System.out.println("app".compareTo("apple"));   // -2(3-5)
        
        // 特殊字符比较
        System.out.println("!".compareTo("A"));        // -33('!'(33) - 'A'(65))
    }
}

使用技巧

  1. 字符串排序:结合 Arrays.sort() 实现字典排序

    String[] fruits = {"Banana", "apple", "Cherry"};
    Arrays.sort(fruits); // 排序结果:["Banana", "Cherry", "apple"]
    
  2. 自定义排序规则:在 Comparator 中组合使用

    List<String> words = Arrays.asList("Data", "base", "System");
    words.sort((s1, s2) -> s1.compareTo(s2)); // 字典序排序
    
  3. 范围比较:检查字符串是否在某个范围内

    boolean inRange = "cat".compareTo("apple") > 0 
                   && "cat".compareTo("dog") < 0;
    

常见错误

  1. 忽略大小写敏感性

    // 错误:期待"Apple"=="apple",实际返回-32
    if ("Apple".compareTo("apple") == 0) { ... }
    

    解决方案:使用 compareToIgnoreCase()

  2. 空指针异常

    String str = null;
    str.compareTo("test"); // 抛出 NullPointerException
    
  3. 错误理解返回值

    // 错误:认为返回值只有 -1/0/1
    int result = "a".compareTo("b"); // 实际返回 -1
    result = "a".compareTo("c");     // 返回 -2(非-1)
    

注意事项

  1. Unicode 依赖:比较基于字符的 Unicode 编码

    • 数字 < 大写字母 < 小写字母
    • 特殊字符位置取决于 Unicode 值
  2. 长度处理

    "hello".compareTo("hello!"); // 返回 -1(长度差)
    
  3. 语言特性

    • 不适用于本地化排序(如德语 ä 排序)
    • 重音字符按 Unicode 值排序(é > z)

最佳实践与性能优化

  1. 空安全处理

    public static int safeCompare(String s1, String s2) {
        if (s1 == null && s2 == null) return 0;
        if (s1 == null) return -1;
        if (s2 == null) return 1;
        return s1.compareTo(s2);
    }
    
  2. 性能优化

    • 短路比较:方法在发现第一个不同字符时即返回
    • 长度优先:对长度差异大的字符串,先比较长度
      if (s1.length() != s2.length()) {
          return s1.length() - s2.length();
      }
      
  3. 替代方案选择 | 场景 | 推荐方法 | |---------------------|------------------------| | 不区分大小写 | compareToIgnoreCase()| | 本地化排序 | Collator.compare() | | 相等性检查 | equals() |

  4. 高效比较模式

    // 先检查引用相等性
    if (str1 == str2) return 0;
    // 再比较内容
    return str1.compareTo(str2);
    

总结

关键点 说明
核心功能 基于 Unicode 的字典顺序比较
大小写处理 区分大小写(A < a)
返回值 字符 Unicode 差值或长度差
时间复杂度 O(min(n,m)) 最坏情况
空指针风险 参数为 null 时抛出 NPE
适用场景 排序、范围检查、有序集合操作

实践建议

✅ 排序操作时直接用于 Collections.sort()
✅ 需要空安全时封装辅助方法
✅ 本地化排序使用 java.text.Collator
❌ 不要依赖返回值具体数值(仅关注正负)
❌ 避免用于相等性检查(用 equals() 更清晰)

最终提示

Java 11+ 中,"str1".compareTo("str2")Comparator.naturalOrder() 行为一致,在排序容器(如 TreeMap)中会自动使用此比较逻辑。