• String -- 从源码剖析String类


    几乎所有的 Java 面试都是以 String 开始的,String 源码属于所有源码中最基础、最简单的一个,对 String 源码的理解也反应了你的 Java 基础功底。

     String 是如何实现的?它有哪些重要的方法?

    以主流的 JDK 版本 1.8 来说,String 内部实际存储结构为 char 数组,源码如下:

     源码中包含下面几个重要的方法:

    1.多构造方法

    String字符串有以下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());
    }

    其中,比较容易被我们忽略的是以 StringBuffer 和 StringBuilder 为参数的构造函数,因为这两种数据类型,我们通常都是单独使用的。

    若您想了解三者的区别请查阅我的另一篇博文,谢谢。

    String、StringBuffer 和 StringBuilder 的区别

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

    源码如下:

     1  public boolean equals(Object anObject) {
     2         // "==" 比较的是引用对象的内存地址,对象引用相同直接返回 true
     3         if (this == anObject) {
     4             return true;
     5         }
     6         // 判断需要对比的值是否为 String 类型,如果不是则直接返回 false
     7         if (anObject instanceof String) {
     8             String anotherString = (String)anObject;
     9             int n = value.length;
    10             if (n == anotherString.value.length) {
    11                 // 把两个字符串都转换为 char 数组对比
    12                 char v1[] = value;
    13                 char v2[] = anotherString.value;
    14                 int i = 0;
    15                 // 循环比对两个字符串的每一个字符
    16                 while (n-- != 0) {
    17                      // 如果其中有一个字符不相等就 true false,否则继续对比
    18                      if (v1[i] != v2[i])
    19                      return false;
    20                     i++;
    21                 }
    22                 return true;
    23             }
    24         }
    25         return false;
    26 }

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

    如果您想了解instanceof和isInstance的区别和用法还有“==”和equals的区别和使用,请查看以下文章:

    instanceof和isInstance的区别

    “==”和equals的区别

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

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

     1 public int compareTo(String anotherString) {
     2     int len1 = value.length;
     3     int len2 = anotherString.value.length;
     4     // 获取到两个字符串长度最短的那个 int 值
     5     int lim = Math.min(len1, len2);
     6     char v1[] = value;
     7     char v2[] = anotherString.value;
     8 
     9     int k = 0;
    10     //对比每一个字符
    11     while (k < lim) {
    12         char c1 = v1[k];
    13         char c2 = v2[k];
    14         // 有字符不相等就返回差值
    15         if (c1 != c2) {
    16             return c1 - c2;
    17         }
    18         k++;
    19     }
    20     return len1 - len2;
    21 }         

    从源码中可以看出,compareTo()方法会循环对比所有的字符,当两个字符串中有任意一个字符不相同时,则return char1-char2。比如,两个字符串分别存储的是1和2,返回的值是 -1;如果存储的是 1 和 1,则返回的值是 0 ,如果存储的是 2 和 1,则返回的值是 1。

    可以看出 compareTo() 方法和 equals() 方法都是用于比较两个字符串的,但它们有两点不同:

    (1)equals() 可以接收一个 Object 类型的参数,而 compareTo() 只能接收一个 String 类型的参数;

    (2)equals() 返回值为 Boolean,而 compareTo() 的返回值则为 int。

    总结:它们都可以用于两个字符串的比较,当 equals() 方法返回 true 时,或者是 compareTo() 方法返回 0 时,则表示两个字符串完全相同。

    4.其他重要方法

    length():查询字符串的长度;

    split():把字符串分割并返回字符串数组;

    trim():去掉字符串首尾空格;

    join():把字符串数组转为字符串;

    replace():替换字符串中的某些字符;

    contains():查询字符串中是否包含另一个字符串;

    indexOf():查询字符串首次出现的下标位置;

    lastIndexOf():查询字符串最后出现的下标位置;

    toLowerCase():把字符串全部转换成小写;

    toUpperCase():把字符串全部转换成大写;

    希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。

    扫描下方二维码关注微信公众号,您会收到更多优质文章推送。

  • 相关阅读:
    4级搭建类403-Oracle 12cR2 DG 搭建(WinServer 2019 一对一 LGWR ASYNC CDB模式)
    4级搭建类402-Oracle 11gR2 DG搭建(WinServer 2019 一对一 LGWR ASYNC)
    12c OCP考试专项 [1z0-071]-Q23: alias别名的使用(2020.06.21)
    12c OCP考试专项 [1z0-071]-Q22: 小计合计(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q21: 日期返回格式(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q20: 集合操作符(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q19: 升序降序/最大值排序(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q18: IS NOT NULL 查询空值及 DISTINCT 去重用法(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q17: 对象权限的授权(2020.06.18)
    12c OCP考试专项 [1z0-071]-Q16: 对象权限的授权(2020.06.18)
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/12496556.html
Copyright © 2020-2023  润新知