• String源码分析


    • 基于JDK1.8版本

    1、类、接口、成员

    
    // 不变类,可序列化,可内部比较,字符序列
    
    public final class String
        implements java.io.Serializable, Comparable<String>,  {
    
        private final char value[];  // String是由char数组组成,由于设置为private final,且不提供公共方法获取,内部不可变由设计人员控制,故为不可变类。
    
        /** Cache the hash code for the string */
        private int hash; // 哈希码,初始默认值为0,由hashCode方法设置。
    
    

    2、长度

        public int length() {
            return value.length; //返回字符数组长度
        }
    

    3、是否为空

        public boolean isEmpty() {
            return value.length == 0; // 通过数组长度是否为0判断
        }
    

    4、根据下标获取字符

        public char charAt(int index) {
            if ((index < 0) || (index >= value.length)) {
                throw new StringIndexOutOfBoundsException(index); // 如果index小于0,或大于字符数组长度,抛出错误
            }
            return value[index]; // 直接通过下标访问数组元素
        }
    

    5、和其他对象比较是否相等

        public boolean equals(Object anObject) {
            if (this == anObject) { // 直接通过==判断对象地址是否相等,若相等,即返回true
                return true;
            }
            if (anObject instanceof String) { // 判断对象是否为String类,若是,往下走
                String anotherString = (String)anObject; // 把Object转为String类
                int n = value.length; 
                if (n == anotherString.value.length) { // 判断两个String长度是否相等,若相等,比较数组中的字符是否相等
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) { // 从头遍历到尾部,一旦出现不相等的字符,就返回false
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true; // 完成遍历,说明相等
                }
            }
            return false; // anObject不属于String类
        }
    

    6、忽略大小写进行相等比较

        public boolean equalsIgnoreCase(String anotherString) {
            return (this == anotherString) ? true
                    : (anotherString != null)
                    && (anotherString.value.length == value.length)
                    && regionMatches(true, 0, anotherString, 0, value.length); // 进行匹配
        }
    
        public boolean regionMatches(boolean ignoreCase, int toffset, 
                String other, int ooffset, int len) {
            char ta[] = value;
            int to = toffset; // 起始位置
            char pa[] = other.value;
            int po = ooffset; // 起始位置
            // Note: toffset, ooffset, or len might be near -1>>>1.
            if ((ooffset < 0) || (toffset < 0)
                    || (toffset > (long)value.length - len)
                    || (ooffset > (long)other.value.length - len)) { // 起始位置合法性
                return false; 
            }
            while (len-- > 0) {
                char c1 = ta[to++];
                char c2 = pa[po++];
                if (c1 == c2) { // 开始判断字符,相等继续
                    continue;
                }
                if (ignoreCase) { // 忽略大小写
                    // If characters don't match but case may be ignored,
                    // try converting both characters to uppercase.
                    // If the results match, then the comparison scan should
                    // continue.
                    char u1 = Character.toUpperCase(c1); // 先同一进行大写转换
                    char u2 = Character.toUpperCase(c2);
                    if (u1 == u2) {
                        continue;
                    }
                    // Unfortunately, conversion to uppercase does not work properly
                    // for the Georgian alphabet, which has strange rules about case
                    // conversion.  So we need to make one last check before
                    // exiting.
                    // 转换为大写不能正常工作,我们需要做最后一次检查。
                    if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
                        continue;
                    }
                }
                return false;
            }
            return true;
        }
    

    7、比较两个字符串词典

        public int compareTo(String anotherString) {
            int len1 = value.length;
            int len2 = anotherString.value.length;
            int lim = Math.min(len1, len2); // 获取两个String中最小长度,比较完最小长度的字符便可判断出,谁排在前面
            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; // 前面相等,则比较长度,负数排在前面
        }
    

    8、生成hash码

    public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i]; 
                    // hash函数式,推导公式val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1],
                    // 31为素数,根据素数的特性,与素数相乘得到的结果比其他方式更容易产生唯一性,也就是说产生 hash 值重复的概率比较小。
                }
                hash = h;
            }
            return h;
        }
    

    9、

  • 相关阅读:
    python接口之request测试:以json格式发送post请求,.json方法,查看响应结果的情况
    python字典转化成json格式。JSONEncoder和JSONDecoder两个类来实现Json字符串和dict类型数据的互相转换
    webservice接口测试wsdl,参数是xml格式。python,入参转化成str,返回值转化成dict调用
    jenkins配置自动发送邮件,抄送
    让 Python 的1、数据库查询返回字典记录--- 2、利用zip函数将两个列表(list)组成字典(dict)
    如何从日期对象python获取以毫秒(秒后3位小数)为单位的时间值?
    Python之测试webservice接口
    eclipese pyDEV安装----可以直接运行python文件
    jenkins安装与配置---windows系统,war直接运行
    python pip 安装第三方库 mysql模块步骤--pip install mysql-connector-python
  • 原文地址:https://www.cnblogs.com/sanjun/p/9851571.html
Copyright © 2020-2023  润新知