使用java语言做开发的朋友,经常会写到判断两个字符串内容是否相同的逻辑。
都知道要判断两个字符串内容是否相同的话,是要使用“equals”方法去判断,而不是用“==”去判断。
那equals方法怎么就做到了判断两个字符串内容是否相同的呢。
下面我带大家一起来深入到java.lang.String类中看看吧。
01equals方法的源码阅读
前提:java.lang.String底层是通过一个char数组实现的。
我们来阅读一下这段源码。
equals方法是由一个字符串对象来调用的,我们这里称之为“自己”(也就是代码中的this)。方法的参数是用来判断是不是与“自己”内容相同的一个入参,我们就简单称之为“入参”吧。
代码中首先判断了“自己”和“入参”是否是同一个对象,如果是同一个对象,内容肯定是相同的了,直接返回true。
然后判断“入参”是否是一个字符串类型的对象(instanceof关键字就是用来判断一个对象是否是指定类型的对象)。如果是才有必要进行后续的判断,如果不是那内容肯定不会相同了。
如果“入参”是一个字符串对象,那就需要再判断一下“自己”和“入参”底层存放的char数组的长度是否一致吧。一致才有可能相同,不一致的话也就没有必要再做后续比较了。
“自己”和“入参”底层存放的char数组长度一致的话,那就需要逐一(循环)判断数组中的内容了。如果循环中发现有一组对应的数组元素不一致的话,那就说明两个字符串内容是不同的,就返回false了。如果循环结束也没有发现有不同的内容,那就说明内容一致,返回true。
02equalsIgnoreCase源码阅读
上面我们阅读的是equals方法,是用来判断两个字符串内容是否完全一致。但有的时候我们可能需要判断两个字符串里的内容如果包含的字母是相同的,不区分大小写的话要怎么办呢?
java.lang.String给我们提供了equalsIgnoreCase方法来实现这个功能。
那具体是怎么实现的呢,我们再来阅读一下源码。
和equals方法类似,也是先判断是否是同一个对象,如果是同一个对象则直接返回true。
如果不是同一个对象,要同时符合“入参”不是null,“自己”和“入参”存放的char数组长度相同,regionMatches比对结果为true这三个条件才返回true。
那regionMatches的逻辑是什么呢,我们再深入进去看一下。
这个方法的代码比较长,为了不影响阅读,只截取了关键判断逻辑,上面有一些参数的校验没有截取进来,有兴趣的朋友可以自己再去翻翻源码。
我们来阅读一下。
这里的逻辑和equals一样,也是循环两个字符串的char数组做比较。
如果相同则比较下一对数组元素(continue)。
如果不同,则将正在比较的一对数组元素都转换为大写,再进行比较,如果相同则比较下一对数组元素。
这里比较完成后,怎么还要转换成小写再比较一次呢。这是因为我们拘泥于英文大小写字母的转换规则了。这里源码给出了解释(转换成小写进行比较的逻辑上的注释),“格鲁吉亚字母,它有奇怪的大小写转换规则。所以我们需要在离开前做最后一次检查”。(到底是怎么样的奇怪的规则,我也没有去研究,有知道的朋友,希望可以在留言区给我们科普一下)。
如果经过这几次比较这一对数组元素都不同,那说明不符合规则,返回false。
今天的内容就写到这里了,希望对你有所帮助。