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() 的解释:
官方已经注明,比较的前提是:当且仅当该参数不为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字符串的比较分析,附上了源码,分析了易错点,总体来说还是比较详细、全面的。
希望对大家有用!