两个字符串一样,但是equls比较却是false的解决办法

本文介绍了一种解决因字符串编码不同导致的问题的方法,通过提供两个实用的Java方法,能够有效处理UTF-8 BOM(字节顺序标记)并比较两个字符串是否相等,即使它们的编码方式不同。

出现这种情况,极有可能就是两个字符串的编码不同。解决办法:
直接两个方法拷过去
public static String deleteUTF8Bom(String fileStr) {
byte[] UTF8_BOM_BYTES = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
byte[] bytes = fileStr.getBytes();
if (bytes[0] == UTF8_BOM_BYTES[0]
&& bytes[1] == UTF8_BOM_BYTES[1]
&& bytes[2] == UTF8_BOM_BYTES[2]) {
return new String(bytes, 3, bytes.length - 3);
}
return fileStr;
}

public static boolean equlsTwoString(String one,String two){
    if(!one.equals(two)){
        if(deleteUTF8Bom(one).equals(deleteUTF8Bom(two))){
            return true;
        }else {
            return false;
        }
    }else {
        return true;
    }
}
在 Java 中,`equals` 方法用于比较两个对象的内容是否相等,而不是它们的引用地址。对于字符串而言,`String` 类重写了 `Object` 类中的 `equals` 方法,使其能够比较字符串的实际字符内容。 当两个不同的 `String` 对象拥有相同的字符序列时,调用 `equals` 方法会返回 `true`。这是因为 `String` 类的 `equals` 方法内部会逐个字符地比较两个字符串是否完全相同[^1]。 下面是一个简单的例子来展示这一点: ```java String str1 = new String("hello"); String str2 = new String("hello"); // 使用 equals 方法比较两个不同的字符串对象 System.out.println(str1.equals(str2)); // 输出: true ``` 在这个例子中,尽管 `str1` 和 `str2` 是两个不同的对象(它们在堆内存中的地址不同),但是它们包含相同的字符序列 `"hello"`,因此 `str1.equals(str2)` 返回 `true`。 值得注意的是,如果直接使用 `==` 运算符,则会比较的是对象的引用是否指向同一块内存区域。例如: ```java String str3 = "world"; String str4 = "world"; // 使用 == 比较两个字符串变量 System.out.println(str3 == str4); // 输出: true 或者 false 取决于字符串池的情况 ``` 在某些情况下,如字符串字面量相同且存在于字符串常量池中时,`str3 == str4` 可能会返回 `true`,但这并不是因为它们的内容相同,而是因为 JVM 优化了字符串存储,让相同的字符串字面量共享同一个实例。然而,在其他情况下,特别是当字符串是通过运行时操作创建的时候,`==` 很可能会返回 `false`,即使它们的内容相同[^1]。 为了确保总是比较字符串的内容而不是引用,应该始终使用 `equals` 方法来进行字符串比较。 此外,需要注意的是,如果字符串中存在不可见字符或者空白字符,可能会导致 `equals` 方法返回 `false`,这时可以考虑使用 `trim()` 方法去除前后空格后再进行比较[^2]。 ### 字符串常量池的作用 Java 中的字符串常量池(String Pool)是一个特殊的存储区域,它存储了被 `intern()` 方法处理过的字符串或者直接以字面量形式创建的字符串。当创建一个新的字符串字面量时,JVM 会在字符串池中查找是否存在一个具有相同值的字符串。如果存在,则不会创建新的字符串,而是返回池中已存在的字符串的引用;如果不存在,则会在池中创建这个字符串并返回其引用。 这种机制可以提高性能并节省内存,特别是在需要频繁创建大量相同字符串的情况下。然而,这也意味着对于通过运行时拼接等方式创建的字符串,它们不会自动进入字符串池,除非显式调用了 `intern()` 方法[^1]。 ### 示例代码 以下是一个示例代码,演示了字符串常量池的行为: ```java public class StringPoolExample { public static void main(String[] args) { String str5 = "test"; String str6 = "test"; System.out.println(str5 == str6); // 输出: true String str7 = new String("test"); String str8 = new String("test"); System.out.println(str7 == str8); // 输出: false System.out.println(str7.equals(str8)); // 输出: true // 将字符串放入池中 String str9 = str7.intern(); String str10 = str8.intern(); System.out.println(str9 == str10); // 输出: true } } ``` 在这个例子中,`str5` 和 `str6` 是通过字面量创建的,所以它们指向同一个字符串池中的实例。而 `str7` 和 `str8` 是通过构造函数创建的,因此它们是不同的对象。但是,它们的内容相同,所以 `equals` 方法返回 `true`。最后,通过调用 `intern()` 方法,将这两个字符串放入池中,此时 `str9` 和 `str10` 指向同一个池中的实例。 ### 结论 综上所述,在 Java 中,`equals` 方法用于比较字符串的内容是否相同,而 `==` 运算符用于比较对象的引用是否相同。为了确保正确地比较字符串的内容,应当使用 `equals` 方法。同时,理解字符串常量池的作用可以帮助更好地理解字符串比较的行为。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值