c++ string比较是否相等_String 源码浅析————终结篇

本文详细剖析了C++ String类中用于比较字符串是否相等的相关方法,包括`equals`、`contentEquals`以及相关重载方法的实现原理,涉及字符数组的遍历、长度比较和线程安全性。通过阅读源码,不仅可以理解字符串比较的内部机制,还能提升对C++标准库的理解和使用技巧。
摘要由CSDN通过智能技术生成

0f57f38a243cb0d16b04280e4bb6bb18.png

写在前面

说说这几天看源码的感受吧,其实 jdk 中的源码设计是最值得进阶学习的地方。我们在对 api 较为熟悉之后,完全可以去尝试阅读一些 jdk 源码,打开 jdk 源码后,如果你英文能力稍微过得去,那么源码有相当详细的注释告诉你 api 的含义,具体用法。假设平时在写代码的过程中突然忘记了某个 api 的用法,那么有些新手没读过源码的可能顺手就打开百度或者谷歌,搜索 api 怎么用?哈哈哈,面向谷歌编程,这样的状态可能会让你一年的经验重复n年, 如果是阅读过源码,则直接进去看看源码英文注释,回想一下源码的实现即可使用,而且看过源码后,里面有些代码细节是可以在平时编码的过程中直接借鉴的。

废话有点多啦~~滴滴滴,上车了。。。

上一篇 String 源码浅析(一) 中已经对String前半部分源码做了解析,这篇把剩下的方法粗略的总结下…

String 成员方法

  • 判断字符串是否相等,该方法继承自Object类的重写实现,原则上也是比较字符串中的字符是否相等。
    1 public boolean equals(Object anObject) {
    2 //判断形参跟当前字符串对象地址是否相等,即是否为同一个对象,如果相等,则返回true
    3 if (this == anObject) {
    4 return true;
    5 }
    6 //如果形参为String类型对象
    7 if (anObject instanceof String) {
    8 //强转为String类型对象
    9 String anotherString = (String)anObject;
    10 //当前字符串对象的字符数组长度
    11 int n = value.length;
    12 //如果当前字符串对象的字符数组长度等于形参字符串字符数组长度
    13 if (n == anotherString.value.length) {
    14 //当前字符串字符数组
    15 char v1[] = value;
    16 //形参字符串字符数组
    17 char v2[] = anotherString.value;
    18 //遍历索引起始位置0
    19 int i = 0;
    20 //遍历当前字符串字符数组,每个索引位置的字符与形参字符串索引位置字符比较,如果不相等则返回false
    21 while (n-- != 0) {
    22 if (v1[i] != v2[i])
    23 return false;
    24 i++;
    25 }
    26 return true;
    27 }
    28 }
    29 //以上条件都不满足,最后返回false
    30 return false;
    31}
  • 传入CharSequence接口形参,实际是与StringBuffer,StringBuilder比较是否相等,因为StringBuffer,StringBuilder都实现了CharSequence接口
    1public boolean contentEquals(CharSequence cs) {
    2 //判断形参是否是AbstractStringBuilder抽象类,实则因当传入的是其子类:StringBuffer, StringBuilder
    3 if (cs instanceof AbstractStringBuilder) {
    4 //如果形参是StringBuffer类型对象
    5 if (cs instanceof StringBuffer) {
    6 //同步锁,调用nonSyncContentEquals方法比较两种是否相等
    7 synchronized(cs) {
    8 return nonSyncContentEquals((AbstractStringBuilder)cs);
    9 }
    10 } else {
    11 //如果形参对象是StringBuilder,则调用nonSyncContentEquals方法比较两种是否相等
    12 return nonSyncContentEquals((AbstractStringBuilder)cs);
    13 }
    14 }
    15 // 如果形参是String对象,则直接调用equals方法返回
    16 if (cs instanceof String) {
    17 return equals(cs);
    18 }
    19 // 如果是其他的CharSequence实现类,则遍历,一个个字符进行比较,找到一个字符不相等则直接返回false
    20 char v1[] = value;
    21 int n = v1.length;
    22 if (n != cs.length()) {
    23 return false;
    24 }
    25 for (int i = 0; i < n; i++) {
    26 if (v1[i] != cs.charAt(i)) {
    27 return false;
    28 }
    29 }
    30 //以上代码都不成立,走到最后直接返回true
    31 return true;
    32}
  • 私有方法,非同步方式(线程不安全)比较与 AbstractStringBuilder 是否相等,实则是与其子类:StringBuffer, StringBuilder 比较大小,contentEquals(CharSequence cs)方法中核心比较代码就是调用该方法。
    1 private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
    2 //当前字符串对象字符数组
    3 char v1[] = value;
    4 //获取形参字符数组
    5 char v2[] = sb.getValue();
    6 //当前字符串对象字符数组长度
    7 int n = v1.length;
    8 //如果当前字符串对象字符数组长度不等于形参字符数组长度,则直接返回false
    9 if (n != sb.length()) {
    10 return false;
    11 }
    12 //遍历当前字符串对象字符数组,与形参字符数组逐一比较字符,找到一个字符不相等,则直接返回false
    13 for (int i = 0; i < n; i++) {
    14 if (v1[i] != v2[i]) {
    15 return false;
    16 }
    17 }
    18 //以上条件都不成立,代码走到最后则直接返回true
    19 return true;
    20}
  • 公有方法,比较与StringBuffer对象是否相等,内部实则直接调用的contentEquals(CharSequence cs)方法,可以说该方法是StringBuffer的特别版吧。
    1 public boolean contentEquals(StringBuffer sb) {
    2 return contentEquals((CharSequence)sb);
    3}
  • 匹配两个字符串部分片段是否相等
    1 public boolean regionMatches(int toffset, String other, int ooffset,
    2 int len) {
    3 //当前字符串字符数组
    4 char ta[] = value;
    5 //当前字符串开始比较的起始位置,即偏移量
    6 int to = toffset;
    7 //待比较的字符串字符数组
    8 char pa[] = other.value;
    9 //待比较的字符串起始位置,即偏移量
    10 int po = ooffset;
    11 //索引检查 1.偏移量小于0 2. 偏移量大于总长度-待比较的长度
    12 //以上两种情况直接返回false
    13 if ((ooffset < 0) || (toffset < 0)
    14 || (toffset > (long)value.length - len)
    15 || (ooffset > (long)other.value.length - len)) {
    16 return false;
    17 }
    18 //遍历,找出不相等的字符,则返回false
    19 while (len-- > 0) {
    20 if (ta[to++] != pa[po++]) {
    21 return false;
    22 }
    23 }
    24 //不出意外,最终则返回true
    25 return true;
    26}
  • 匹配两个字符串部分片段是否相等,同时判断是否忽略大小写
    1public boolean regionMatches(boolean ignoreCase, int toffset,
    2 String other, int ooffset, int len) {
    3 //当前字符串字符数组
    4 char ta[] = value;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值