美文网首页
Java源码学习 -- String

Java源码学习 -- String

作者: 缘木与鱼 | 来源:发表于2021-04-24 16:51 被阅读0次

    String 源码学习

    常见面试题:

    String是如何实现的? 有哪些常用的方法?

    回答:

    以主流的 JDK 版本 1.8 来说,String 内部实际存储结构为 char 数组,Java9 以后String的存储由 char 数组 转换成 byte 数组 (转换后的好处:存储变得更加紧凑,占用内存更少,操作性能更高了),源码如下:

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
        /** 用于存储字符串的值. */
        private final char value[];
        
        /**缓存字符串的hash code */
        private int hash; // Default to 0
        
        // ...其他
    }
    

    其它常用的方法:

    1、多构造方法

    下面是4个重要的构造方法:

    /**String 为参数的构造方法*/
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
    
    /**char[] 为参数的构造方法*/
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
    
    /**StringBuffer 为参数的构造方法*/
    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
    
    /**StringBuilder 为参数的构造方法*/
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }
    
    

    2、equals() 比较两个字符串是否相等

    源码如下:

    public boolean equals(Object anObject) {
        // 对象引用相同,直接返回 true
        if (this == anObject) {
            return true;
        }
        // 判断需要对比的值是否为 String 类型,不是则直接返回 false
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            // 如果字符串的长度,再继续进行下面的比较
            if (n == anotherString.value.length) {
                // 把两个字符串都转换成 char 类型进行对比
                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;
            }
        }
        return false;
    }
    

    简要说明方法的使用:

    String 重写了 Object 的 equals() 方法,equals() 方法需要传递一个 Object 类型的参数值,在比较时会先通过 instanceof 判断是否为 String 类型,如果不是则直接返回 false 。 instanceof 的使用为判断 Object 是否为指定的类型,如果是指定的类型返回 true ,不是则返回 false 。

    如:

    Object str = "abc";
    Object a = 123;
    System.out.println(str instanceof String);  // 返回 true
    System.out.println(a instanceof String);    // 返回 false
    

    需要注意的一点是: instanceof 只能用作对象的判断(编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定)。 如下面的代码将编译无法通过:

    int a = 123;
    System.out.println(a instanceof Integer);
    System.out.println(a instanceof String);
    

    还有一个与 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);
    }
    

    3、compareTo() 比较两个字符串

    该方法用于比较两个字符串,返回的结果为 int 类型的值,源码如下:

    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        // 获取到两个字符串长度最短的那个 int 值
        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;
    }
    

    相关文章

      网友评论

          本文标题:Java源码学习 -- String

          本文链接:https://www.haomeiwen.com/subject/uarlrltx.html