首页 > 编程语言 >字符串源码

字符串源码

时间:2024-07-14 12:18:31浏览次数:18  
标签:String int value char 源码 哈希 字符串

String类的声明

// final不可被继承
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
}
  • 比较字符串内容
public boolean equals(Object anObject) {
    // 检查是否是同一个对象的引用,如果是,直接返回 true
    if (this == anObject) {
        return true;
    }
    // 检查 anObject 是否是 String 类的实例
    if (anObject instanceof String) {
        // 将 anObject 强制转换为 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) {
                // 如果在任何位置字符不同,则返回 false
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            // 所有字符都相同,返回 true
            return true;
        }
    }
    // 如果 anObject 不是 String 类型或长度不等,则返回 false
    return false;
}

char 数组优化为 byte 数组

  • Java 9 以前,String 是用 char 型数组实现的,之后改成了 byte 型数组实现,并增加了 coder 来表示编码。这样做的好处是在 Latin1 字符(一种单字节字符集)为主的程序里,可以把 String 占用的内存减少一半。

  • char[]byte[],最主要的目的是节省字符串占用的内存空间。内存占用减少带来的另外一个好处,就是 GC 次数也会减少。

  • JDK11中String类源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    @Stable
    private final byte[] value;
    private final byte coder;
    private int hash;
}

31倍哈希法

public int hashCode() {
    // 从缓存中获取哈希码
    int h = hash;
    // 如果哈希码未被计算过(即为 0)且字符串不为空,则计算哈希码
    if (h == 0 && value.length > 0) {
        // 获取字符串的字符数组
        char val[] = value;
        // 遍历字符串的每个字符来计算哈希码
        for (int i = 0; i < value.length; i++) {
            // 31 倍哈希法: 使用 31 作为乘法因子
            h = 31 * h + val[i];
        }
        // 缓存计算后的哈希码
        hash = h;
    }
    // 返回哈希码
    return h;
}

subString()

  • 截取字符串
public String substring(int beginIndex) {
    // 检查起始索引是否小于 0,如果是,则抛出 StringIndexOutOfBoundsException 异常
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    // 计算子字符串的长度
    int subLen = value.length - beginIndex;
    // 检查子字符串长度是否为负数,如果是,则抛出 StringIndexOutOfBoundsException 异常
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    // 如果起始索引为 0,则返回原字符串;否则,创建并返回新的字符串
    return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

indexOf()

  • 查找一个子字符串在原字符串中第一次出现的位置,并返回该位置的索引
static int indexOf(char[] source, int sourceOffset, int sourceCount,
        char[] target, int targetOffset, int targetCount,
        int fromIndex) {
    // 如果开始搜索的位置已经超出 source 数组的范围,则直接返回-1(如果 target 数组为空,则返回 sourceCount)
    if (fromIndex >= sourceCount) {
        return (targetCount == 0 ? sourceCount : -1);
    }
    // 如果开始搜索的位置小于0,则从0开始搜索
    if (fromIndex < 0) {
        fromIndex = 0;
    }
    // 如果 target 数组为空,则直接返回开始搜索的位置
    if (targetCount == 0) {
        return fromIndex;
    }

    // 查找 target 数组的第一个字符在 source 数组中的位置
    char first = target[targetOffset];
    int max = sourceOffset + (sourceCount - targetCount);

    for (int i = sourceOffset + fromIndex; i <= max; i++) {
        // 如果 source 数组中当前位置的字符不是 target 数组的第一个字符,则在 source 数组中继续查找 target 数组的第一个字符
        /* Look for first character. */
        if (source[i] != first) {
            while (++i <= max && source[i] != first);
        }

        // 如果在 source 数组中找到了 target 数组的第一个字符,则继续查找 target 数组的剩余部分是否匹配
        /* Found first character, now look at the rest of v2 */
        if (i <= max) {
            int j = i + 1;
            int end = j + targetCount - 1;
            for (int k = targetOffset + 1; j < end && source[j]
                    == target[k]; j++, k++);

            // 如果 target 数组全部匹配,则返回在 source 数组中的位置索引
            if (j == end) {
                /* Found whole string. */
                return i - sourceOffset;
            }
        }
    }
    // 没有找到 target 数组,则返回-1
    return -1;
}

trim()

  • 去除字符串两侧的空白字符
public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */

    // 越过左边的空格
    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    // 越过右边的空格
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

字符串不可变

  • 可以保证 String 对象的安全性,避免被篡改

  • 保证哈希值不会频繁变更

  • 可以实现字符串常量池,Java 会将相同内容的字符串存储在字符串常量池中。这样,具有相同内容的字符串变量可以指向同一个 String 对象,节省内存空间

  • 不管是截取substring()、拼接concat(),还是替换replace(),都不是在原有的字符串上进行的,而是重新生成了新的字符串对象。也就是说,这些操作执行过后,原来的字符串对象并没有发生改变

标签:String,int,value,char,源码,哈希,字符串
From: https://www.cnblogs.com/sprinining/p/18301345

相关文章

  • 2024最新修复公众号无限回调系统源码下载
    内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍2024最新修复公众号无限回调系统源码下载微信公众平台回调比较麻烦,还不能多次回调,于是搭建一个多域名回调的源码很有必要。测试环境:Nginx1.24MySQL5.6.50PHP-7.21.创......
  • 去水印小程序源码修复版-前端后端内置接口+第三方接口
    内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍去水印小程序源码,前端+后端,内置接口+第三方接口,修复数据库账号密码错误问题,内置接口支持替换第三方接口,文件挺全的,可以添加流量主代码,搭建需要准备一台服务器,备案域名和http......
  • 响应式UI知识付费系统源码 知识付费软件 教育下载网站模板 知识付费做的最好的平台 视
    内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍这是一款知识付费平台模板,后台可上传本地视频,批量上传视频连接,视频后台可设计权限观看,免费试看时间时长,会员等级观看,付费观看等功能,也带软件app权限下载,帮助知识教育和软件......
  • 【免费】Python数据分析最新87个项目案例,包含说明文档+数据+源码资料合集分享
    Python数据分析最新87个项目案例,包含说明文档+数据+源码。87个完整项目案例获取方式:https://pan.quark.cn/s/589d02b01ce5包含但不限于:“表迪杯“数据分析大赛已题学生校围消费行为分析【项目:深圳市二手房房价分析及预测】【项目:信用卡客户用户画像及贷款违约预测模型......
  • Java计算机毕业设计个人健康管理系统的设计与实现(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着生活节奏的加快和健康意识的增强,个人健康管理成为了现代社会的重要议题。传统医疗模式下,人们往往只在出现症状时才寻求医生的帮助,这种“被动医疗......
  • Java计算机毕业设计的高校疫情防控系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在全球新冠疫情持续蔓延的背景下,高校作为人群密集、流动性大的场所,其疫情防控工作面临着前所未有的挑战。传统的疫情防控手段难以有效应对疫情传播的......
  • Java计算机毕业设计校园二手物品交易平台(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景:随着高等教育的普及与校园生活的日益丰富,学生群体对各类学习资料、生活用品及电子产品的需求日益增长。同时,由于更新换代迅速及经济因素的考量,大量二......
  • 【Android面试八股文】谈谈OkHttp框架的原理(深度剖析源码)
    文章目录一、OkHttp介绍二、OkHttp使用流程三、OkHttp的分发器Dispatcher3.1Dispatcher3.2同步请求3.3异步请求四、OKHttp的请求流程五、分发器线程池六、拦截器责任链6.1责任链模式6.1.1故事背景6.1.2责任链模式实现6.2OkHttp的拦截器流程......
  • 【模板】字符串
    字符串哈希素数:13110612e6+931e7+192e7+933e7+231e9+97LL(1e16)+61Zfunctionn=strlen(s+1),m=strlen(t+1);z[1]=n;For(i,2,n,l=0,r=0){ if(i<=r)z[i]=min(z[i-l+1],r-i+1); while(s[z[i]+1]==s[i+z[i]])++z[i]; if(i+z[i]-1>......
  • 基于SpringBoot+Vue+uniapp的校园美食交流系统的详细设计和实现(源码+lw+部署文档+讲
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......