Java后端:字符串比较(共四种方法,有方法介绍、易错点分析、Java源码,值得一看!)

Java后端:字符串比较(共四种方法,有方法介绍、易错点分析、Java源码,值得一看!)


前言

Java开发中,字符串的比较是非常常见的,可用的方法也很多。
本文主要总结了一些字符串比较方法和易错点,供大家参考和探讨。


一、推荐使用:equals()

equals() 方法将逐个地比较两个字符串的每个字符是否相同。
equals() 源代码如下:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

从源代码中可以看出,如果两个字符串具有相同的字符和长度,它返回 true,否则返回 false。
需要注意的是,字符的大小写也在检查的范围之内。

常见使用方式举例:

String s = "xxx";
方式一 : if("xxx".equals(s)) {...} //推荐
方式二 : if(s.equals("xxx")) {...} //不推荐

两种使用方式理论上都可以,但是更推荐使用方式一,否则可能出现调用 s.equals(“xxx”) 报错:NullPointerException空指针异常,或者false。

可能出错的原因如下:

先看官方对 equals() 的解释:
Alt
官方已经注明,比较的前提是:当且仅当该参数不为null

但是方式二这种,把变量放前面,如果变量为null,就可能报错:NullPointerException空指针异常
因此,更推荐使用方式一,即把常量放在前面,变量放在后面。
小总结:

("a").equals(str)时,如果str为null的时候返回false//推荐,容错性更强
当str.equals("a")时,如果str为null时会抛NullPointerException空指针异常;//不推荐,容错性较低,可能导致业务无法进行

相关参考链接如下:
Java中为什么字符串的比较常量放前面好?
Java - equals 方法变量和常量位置区别
Java字符串比较(3种方法)

二、最容易想到:用Str1 == Str2判断

很多朋友在刚开始开发的时候,很容易想到用 == 的方式来判断两个字符串是否相等。但是实践后发现很难达到预期效果。

原因在于:
== 运算符比较引用而不是具体的值。
通俗来说:== 是比较字符串的存放地址是否相同。
举例说明:

public static void main(String[] args) {
        String s1 = "ABC";
        String s2 = "ABC";
        String s3 = new String("ABC");
        String s4 = new String("ABC");
 
        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s3 == s4);//false
        System.out.println(s1.equals(s3));//true
        System.out.println(s3.equals(s4));//true
}

很多人认为结果都是true,但是实际上,第二个和第三个为false。

s1 == s2 true,是因为 字符"ABC" 的存放地址都相同,所以为true
s1 == s3 false,是因为 s3的字符"ABC" 是new新增的,存放地址是单独开辟的,和s1的不同,所以为false
而s1.equals(s3) true,是因为equals()比较的是值,s1和s3的存放地址不同,但是值相同,所以为true。

这就是为什么字符串比较更推荐使用equals()的原因。

参考链接: 【Java中比较字符串的两种方式】

三、最容易忽略:compareTo()

很多开发者在写代码的时候很容易忽略了 compareTo() 这一个函数,因为这个函数的使用频率确实较低,容易被忽略。但是实际上,用 compareTo() 也能达到字符串比较的效果。

compareTo() 源码如下:

public int compareTo(String anotherString) {
       int len1 = value.length;
       int len2 = anotherString.value.length;
       int lim = Math.min(len1, len2);
       char v1[] = value;
       char v2[] = anotherString.value;

       int k = 0;
       while (k < lim) {
           char c1 = v1[k];
           char c2 = v2[k];
           if (c1 != c2) {
               return c1 - c2;
           }
           k++;
       }
       return len1 - len2;
}

从源码中可以看出,compareTo() 返回值并不是boolean类型的,而是int类型。
方法说明:String 类 compareTo() 方法按字典顺序比较值并返回一个整数值,该值描述第一个字符串是否小于、等于或大于第二个字符串

常见说明如下:

public static void main(String[] args){    
  	String s1= "ab" ;  
   	String s2= "ab" ;  
   	String s3= "bc" ;  
   	System.out.println(s1.compareTo(s2)); //0  
   	System.out.println(s1.compareTo(s3)); //-1(因为s1 < s3)按字典顺序
   	System.out.println(s3.compareTo(s1)); //1(因为 s3 > s1 )按字典顺序
 } 

因此,compareTo() 判断两个字符串是否相等示例如下:

if(s1.compareTo(s2)!=0){...}

四、equlas()拓展:equalsIgnoreCase()

equalsIgnoreCase() 方法的作用和语法与 equals() 方法完全相同,唯一不同的是 equalsIgnoreCase() 比较时不区分大小写。

源码如下:

public boolean equalsIgnoreCase(String anotherString) {
        return (this == anotherString) ? true
                : (anotherString != null)
                && (anotherString.value.length == value.length)
                && regionMatches(true, 0, anotherString, 0, value.length);
    }

equalsIgnoreCase() 方法适合用在对大小写不敏感的地方,其用法本质和equals() 相同。


总结

本文介绍了4种Java字符串的比较分析,附上了源码,分析了易错点,总体来说还是比较详细、全面的。
希望对大家有用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值