1. 概述

本文将深入探讨Java中字符串比较的各种方法。作为Java最常用的数据类型之一,字符串操作是日常开发中的高频需求,而比较操作更是其中的核心场景。

2. 使用String类进行字符串比较

2.1 使用"=="运算符

用"=="比较字符串值是Java新手最容易踩的坑之一。这个运算符只能判断两个字符串是否引用同一对象,而非比较它们的实际内容:

String string1 = "using comparison operator";
String string2 = "using comparison operator";
String string3 = new String("using comparison operator");
 
assertThat(string1 == string2).isTrue();  // ✅ 指向同一字符串常量
assertThat(string1 == string3).isFalse(); // ❌ new创建新对象

关键点:

  • string1string2指向字符串常量池中的同一对象
  • string3通过new创建,生成独立对象
  • 永远不要用"=="比较字符串内容!

2.2 使用equals()

String类重写了Objectequals()方法,逐个字符比较内容,忽略内存地址

String string1 = "using equals method";
String string2 = "using equals method";
String string3 = "using EQUALS method";
String string4 = new String("using equals method");

assertThat(string1.equals(string2)).isTrue();  // ✅ 内容相同
assertThat(string1.equals(string4)).isTrue();  // ✅ 内容相同
assertThat(string1.equals(null)).isFalse();   // ❌ null处理
assertThat(string1.equals(string3)).isFalse(); // ❌ 大小写敏感

核心特性:

  • 严格区分大小写
  • 任一字符串为null时返回false
  • 实际开发中最常用的比较方式

2.3 使用equalsIgnoreCase()

当需要忽略大小写时,equalsIgnoreCase()是最佳选择:

String string1 = "using equals ignore case";
String string2 = "USING EQUALS IGNORE CASE";

assertThat(string1.equalsIgnoreCase(string2)).isTrue(); // ✅ 忽略大小写

典型应用场景:

  • 用户名/密码验证
  • 文件扩展名检查
  • 不区分大小写的配置项匹配

2.4 使用compareTo()

compareTo()按字典序比较字符串,返回int值:

  • 0:相等
  • 负数:调用字符串小于参数字符串
  • 正数:调用字符串大于参数字符串
String author = "author";
String book = "book";
String duplicateBook = "book";

assertThat(author.compareTo(book)).isEqualTo(-1);         // 'a' < 'b'
assertThat(book.compareTo(author)).isEqualTo(1);          // 'b' > 'a'
assertThat(duplicateBook.compareTo(book)).isEqualTo(0);   // 完全相等

⚠️ 注意:此方法区分大小写,且对null敏感(会抛NPE)

2.5 使用compareToIgnoreCase()

compareToIgnoreCase()compareTo()的忽略大小写版本:

String author = "Author";
String book = "book";
String duplicateBook = "BOOK";

assertThat(author.compareToIgnoreCase(book)).isEqualTo(-1);         // 'A' < 'b'
assertThat(book.compareToIgnoreCase(author)).isEqualTo(1);          // 'b' > 'A'
assertThat(duplicateBook.compareToIgnoreCase(book)).isEqualTo(0);    // 忽略大小写相等

3. 使用Objects类比较字符串

Objects.equals()是更安全的比较方式,先比较引用再比较内容

String string1 = "using objects equals";
String string2 = "using objects equals";
String string3 = new String("using objects equals");

assertThat(Objects.equals(string1, string2)).isTrue();  // ✅ 引用相同
assertThat(Objects.equals(string1, string3)).isTrue();  // ✅ 内容相同
assertThat(Objects.equals(null, null)).isTrue();        // ✅ 双null处理
assertThat(Objects.equals(null, string1)).isFalse();    // ❌ 单null处理

优势对比: | 方法 | null安全 | 比较方式 | 性能 | |------|----------|----------|------| | Objects.equals() | ✅ | 引用→内容 | 稍慢 | | String.equals() | ❌ | 直接内容 | 最快 |

4. 使用Apache Commons库

Apache Commons的StringUtils提供了更强大的字符串比较工具。

4.1 equals()和equalsIgnoreCase()

增强版比较方法,完美处理null值:

// equals() 示例
assertThat(StringUtils.equals(null, null)).isTrue();              // ✅ 双null
assertThat(StringUtils.equals(null, "equals method")).isFalse();   // ❌ 单null
assertThat(StringUtils.equals("equals method", "equals method")).isTrue(); // ✅ 内容匹配
assertThat(StringUtils.equals("equals method", "EQUALS METHOD")).isFalse(); // ❌ 大小写敏感

// equalsIgnoreCase() 示例
assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")).isTrue(); // ✅ 忽略大小写

4.2 equalsAny()和equalsAnyIgnoreCase()

批量比较利器,检查字符串是否匹配任意候选值:

// equalsAny() 示例
assertThat(StringUtils.equalsAny(null, null, null)).isTrue();                    // ✅ 全null
assertThat(StringUtils.equalsAny("equals any", "equals any", "any")).isTrue();   // ✅ 匹配任意
assertThat(StringUtils.equalsAny("equals any", null, "equals any")).isTrue();    // ✅ 包含匹配
assertThat(StringUtils.equalsAny(null, "equals", "any")).isFalse();              // ❌ 无匹配
assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")).isFalse();   // ❌ 大小写敏感

// equalsAnyIgnoreCase() 示例
assertThat(StringUtils.equalsAnyIgnoreCase("ignore case", "IGNORE CASE", "any")).isTrue(); // ✅ 忽略大小写

4.3 compare()和compareIgnoreCase()

null安全的字典序比较,默认认为null小于非空字符串

// compare() 示例
assertThat(StringUtils.compare(null, null)).isEqualTo(0);   // ✅ 双null相等
assertThat(StringUtils.compare(null, "abc")).isEqualTo(-1);  // ✅ null < 非空
assertThat(StringUtils.compare("abc", "bbc")).isEqualTo(-1); // ✅ 'a' < 'b'
assertThat(StringUtils.compare("bbc", "abc")).isEqualTo(1);  // ✅ 'b' > 'a'

// compareIgnoreCase() 示例
assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")).isEqualTo(-1); // ✅ 'A' < 'b'
assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")).isEqualTo(1);   // ✅ 'b' > 'A'
assertThat(StringUtils.compareIgnoreCase("abc", "ABC")).isEqualTo(0);   // ✅ 忽略大小写相等

高级用法:通过nullIsLess参数控制null的排序位置:

assertThat(StringUtils.compare(null, "abc", true)).isEqualTo(-1);  // ✅ null更小
assertThat(StringUtils.compare(null, "abc", false)).isEqualTo(1);  // ✅ null更大

5. 总结

Java字符串比较方法选择指南:

场景 推荐方法 特点
严格内容比较 String.equals() 高性能,区分大小写
忽略大小写 equalsIgnoreCase() 常用于用户输入
null安全比较 Objects.equals() 防御性编程首选
批量匹配 StringUtils.equalsAny() 简化多值判断
排序需求 StringUtils.compare() 完美处理null排序

💡 经验之谈:日常开发中90%的场景用equals()足够,但处理用户输入或外部数据时,StringUtilsnull安全方法能避免大量NPE问题。

完整示例代码见GitHub仓库


原始标题:Comparing Strings in Java | Baeldung

« 上一篇: Java对象类型转换