方法定义

public boolean equals(Object anObject)

所属类java.lang.String

参数

  • anObject:要与此字符串进行比较的对象

返回值

  • true:如果给定对象与该字符串内容相等(字符序列相同)
  • false:否则

功能说明

String.equals() 方法用于比较两个字符串的内容是否相等,它会逐个字符比较两个字符串的字符序列。该方法区分大小写

== 运算符不同,equals() 比较的是内容,而 == 比较的是引用(内存地址)

示例代码

基本用法

public class StringEqualsExample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "hello";
        String str4 = new String("Hello");
        
        // 内容相同,返回 true
        System.out.println(str1.equals(str2)); // true
        
        // 内容不同(大小写不同),返回 false
        System.out.println(str1.equals(str3)); // false
        
        // 内容相同,即使使用 new 创建,返回 true
        System.out.println(str1.equals(str4)); // true
        
        // 与 null 比较,返回 false
        System.out.println(str1.equals(null)); // false
    }
}

== 的对比

String a = "Java";
String b = "Java";
String c = new String("Java");

System.out.println(a == b);      // true (字符串常量池)
System.out.println(a == c);      // false (不同对象)
System.out.println(a.equals(b)); // true (内容相同)
System.out.println(a.equals(c)); // true (内容相同)

使用技巧

1. 避免空指针异常的技巧

// 不安全的方式(可能抛出 NullPointerException)
if (str.equals("target")) { ... }

// 安全的方式
if ("target".equals(str)) { ... }

// 或使用 Objects.equals() (推荐)
if (Objects.equals(str, "target")) { ... }

2. 忽略大小写的比较

// 使用 equalsIgnoreCase()
if (str1.equalsIgnoreCase(str2)) {
    System.out.println("内容相同,忽略大小写");
}

3. 在集合中使用

List<String> list = Arrays.asList("apple", "banana", "cherry");
boolean contains = list.contains("Apple"); // false (区分大小写)
boolean containsIgnoreCase = list.stream()
    .anyMatch(s -> s.equalsIgnoreCase("Apple")); // true

常见错误

1. 混淆 ==equals()

String a = new String("test");
String b = new String("test");
System.out.println(a == b);     // false (错误!比较的是引用)
System.out.println(a.equals(b)); // true (正确!比较的是内容)

2. 忽略 null 值导致的空指针异常

String str = null;
// 下面代码会抛出 NullPointerException
// if (str.equals("hello")) { ... }

3. 在 switch 语句中使用(Java 7+ 才支持)

// Java 7 之前不支持
// switch(str) { ... } // 编译错误

// Java 7+ 支持,但内部仍使用 equals()
switch(str) {
    case "hello":
        System.out.println("Hello!");
        break;
}

注意事项

  1. 区分大小写"Hello".equals("hello") 返回 false
  2. null 安全性:调用 null.equals() 会抛出 NullPointerException
  3. 性能考虑:对于大量字符串比较,考虑使用 switch 语句(Java 7+)或哈希查找
  4. 字符编码:确保比较的字符串使用相同的字符编码
  5. 国际化问题:某些语言的字符比较可能需要特殊处理(如德语的 ß)

最佳实践

1. 使用常量在前的方式避免空指针

// 推荐
if ("constant".equals(variable)) { ... }

// 不推荐(可能抛出异常)
if (variable.equals("constant")) { ... }

2. 使用 Objects.equals() 方法

import java.util.Objects;

// 自动处理 null 值
if (Objects.equals(str1, str2)) {
    // 安全的比较,null 与 null 返回 true,null 与非 null 返回 false
}

3. 对于频繁比较的场景,考虑缓存

// 如果需要频繁比较同一字符串
String target = "important_value".intern(); // 放入字符串常量池
// 后续比较可能更快(但 intern() 有性能开销,需权衡)

4. 使用合适的比较方法

// 根据需求选择
equals()           // 区分大小写
equalsIgnoreCase() // 忽略大小写
compareTo()        // 返回排序顺序
compareToIgnoreCase() // 忽略大小写的排序

性能优化

  1. 字符串常量池:使用字符串字面量而非 new String() 可以利用常量池,提高 == 比较的概率
  2. 长度预检查equals() 方法内部会先检查长度,长度不同直接返回 false
  3. 避免重复比较:缓存比较结果,特别是对于复杂逻辑
  4. 考虑使用 switch:对于多个固定值的比较,switch 语句可能比多个 if-else 更高效
  5. 使用 StringBuilder 时注意StringBuilder 没有重写 equals(),需要转换为 String
StringBuilder sb = new StringBuilder("test");
// sb.equals("test") 会返回 false(比较的是对象引用)
String result = sb.toString();
result.equals("test"); // true

总结

String.equals(Object obj) 是 Java 中最常用的字符串比较方法,关键要点:

  1. 功能核心:比较字符串内容是否相等(区分大小写)
  2. == 的区别== 比较引用,equals() 比较内容
  3. null 安全:注意避免空指针异常,推荐使用 "constant".equals(variable)Objects.equals()
  4. 最佳实践:根据场景选择合适的比较方法,注意性能和可读性
  5. 常见错误:混淆 ==equals(),忽略 null 值处理

掌握 String.equals() 方法是 Java 开发的基础,正确使用它能避免大量潜在的 bug。在实际开发中,结合 Objects.equals() 和适当的 null 检查,可以写出更健壮的代码。