zoukankan      html  css  js  c++  java
  • Java面试准备之String类专项突破+源码分析

    String的源码中有很多Arrays的方法使用,建议先参阅Arrays的类库

    基本介绍:

      String是一个比较特殊的类,有很多种建立的方法。

      如果使用传统的构造方法比如 String s = new String("字符串");这时的对象会在堆上分配,这时候比较两个字符串地址就不相等,而用""双引号包起来的内容会在常量池中做停留,这时如果有两个内容一样的地址就一样了。

      因此,使用==来比较字符串是不靠谱的。

      String类还实现了三个接口:Serializable, CharSequence, Comparable<String>。

      serializable只是可序列化的标记,不用去管它。

      CharSequence这个接口为String提供了三个个很重要的方法:

        charAt(int index),可以返回索引的值

        length(),返回字符串序列长度

          subSequence(int start,int end),看名字就明白了,返回一个子序列

       comparable是相当重要的一个接口了(看它的子类就知道了),作用这里搬运以下JavaDOC中的原文。

        作用:此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。

        这个接口可以实现集合或者数组的排序,自然地,字符串的排序也少不了它。

        只有一个compareTo()来实现。

    类库使用:

       Java中每个类的类库中的方法实在是太多了,在此不想做一个简单的罗列,我们尽量按照设计一个类的思考方式去熟悉一些方法,再配合源码的解析,应该会理解的比较清楚。

      假设,我们是Java语言的设计者(当然不是那么正规的),现在,我们已经给String这个类实现了三个接口,那么第一件事,肯定是重写这些接口了。

      把握String本质还是char型数组的原则,

        charAt(int index)方法被重写成了一个获取数组中第index个字符的方法

        length()方法就返回了数组的长度,这时候记忆两个"length"就很容易了,String调用的是一个方法所以是length(),而这个方法中又调用了数组的一个属性length

        subSequence()方法被重写成调用了subString方法,而在subString方法中进行一系列边界检查之后,调用了一个构造方法,最后调用了Arrays.copyOfRange()方法

        compareTo是最复杂的一个,它实现了两个字符串的比较。它循环比较了第一个不同的字符,并返回他们的差值,如果都相同则返回0。这个方法对外来看就是本字符串字典顺序小于被比较的字符串,返回  一个小于0的数,反之返回大于0的数;

        
     1  public int compareTo(String anotherString) {
     2         int len1 = value.length;
     3         int len2 = anotherString.value.length;
     4         int lim = Math.min(len1, len2);
     5         char v1[] = value;
     6         char v2[] = anotherString.value;
     7 
     8         int k = 0;
     9         while (k < lim) {
    10             char c1 = v1[k];
    11             char c2 = v2[k];
    12             if (c1 != c2) {
    13                 return c1 - c2;
    14             }
    15             k++;
    16         }
    17         return len1 - len2;
    18     }
    View Code

      现在,我们实现了所有接口方法,该干一点Sting自己的事了

        首先是构造方法,在此不再赘述,但是大量的构造方法用到了Arrays.copy()这个静态方法。

        然后应该是判定了:

          是否为空:isEmpty()

          是否以特定字符串开头或结尾:startWith(),endWith()

          是否包含某字符串:contains(CharSequence s),注意参数,我们仍可以用String代替

          是否与某个字符串相等: equals(Object),源码中将Object转换为String之前,使用了instanceof判断此Object是不是String类型的,避免了抛出异常。

          是否与某个字符串相等(不考虑大小写):equalsIgnoreCase(),基本所有的不考虑大小写的用法都这么加一个后缀

        再然后应该是拆分,合并:

          替换:替换字符:replace(char old, char new)

             替换字符串:replace(CharSequence target, CharSequence replacement)

             替换所有字符串,但是第一个参数是一个正则表达式:replaceAll(String regex, String replacement)

             替换第一个字符串,但是第一个参数是一个正则表达式:replaceFirst(String regex, String replacement)

          分割:按照指定的正则表达式拆分字符串,返回值是一个字符串数组:split(String regex)

             返回一个子字符串:substring(int beginIndex, int endIndex)

             忽略前后的空白:trim()

          合并: 将指定字符串连接到此字符串的结尾:concat(String str)

          转换:将数组转换成字符串:copyValueOf(char[] data)

             将字符串转换成数组:toCharArray()

             大小写转换:toLowerCase(),toUpperCase()

             将各种类型转换成字符串:各种valueOf(Any b)

    -----------------------------------------------------

    Github:

    https://github.com/RainFool
  • 相关阅读:
    vue中封装公共方法,全局使用
    element-ui table 最后一行合计,单元格合并
    vuex 进行封装
    vue生命周期
    (转)no terminal library found
    解压
    (转)bash: make: command not found
    (转)linux 批量删除文件命令
    python
    Session
  • 原文地址:https://www.cnblogs.com/RainFool/p/3912953.html
Copyright © 2011-2022 走看看