String源码赏析

1,007 阅读2分钟

经常使用,创建String,却没看过String的源码,今天看完之后受益匪浅。大到每个方法,小到每个变量,都有其存在的理由,代码的规范就该如此。

常量定义

  • char value[]; 存储字符

  • int hash; 字符串对应的hash值。默认为0

System.arraycopy()

这个方法可谓是用的相当频繁,之前ArrayList扩容就是用的arraycopy()方法,在字符串中也大量使用。

static native void arraycopy(Object src,int srcPos, Object dest, int destPos,int length);
  • src 源数组

  • srcPos 原数组中的起始位置

  • dest 目标数组

  • destPos 目标数组中的起始位置

  • length 要复制的源数组元素的数量

equals方法

concat方法

  1. 创建char数组,然后使用System.arraycopy()拷贝value值后返回新数组buf[]

    char[] copy = new char[newLength]; // 创建char数组Copy
    // original  原始字符串的值     copy  拷贝到的目标数组  拷贝的长度System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); 
    return copy;
    
  2. 调用System.arraycopy()方法把需要连接的字符串拼接到buf[]

    System.arraycopy(value, 0, dst, dstBegin, value.length); // value追加的字符串  dst 目标数组  dstBegin目标数组的起始位置  拷贝的长度
    
  3. 新建一个string对象返回

replace方法

indexOf方法

  • @1:first , target中需要查找的字符串的首字符
  • @2:  target本身具有长度,当下标大于sourceCount - targetCount时,source中就不可能出现target字符串。
  • @3: 如果source[i] 不等于first,定位到source数组中第一次出现first字符的位置
  • @4:当source[i+1, end) == target[targetOffset, end)时,说明存在字符串target。返回

compareTo方法

两个字符串比较最终是字符数组中字符的ASCII码的比较。如果在【0, lim】范围内两个字符不相等,返回字符ASCII的差,相等的话返回两个字符串的长度差

trim方法

其实就是把value数组中通过移动下标来截取value数组

startsWith方法

通过移动to,po下标来判断字符串value是否以prefix开始

总结

看到方法名脑海中有大致的实现思路。但是跟随其实现的步骤,才发现自己的思路太啰嗦了。三五行实现的代码让自己写,写出了十几行。不得不佩服其实现思路和代码能力。

  • (比较方法)在执行其比较逻辑之前通过卫语句已经过滤掉大部分情况。
  • 使用大量的 --pc,to++等减少代码行数
  • 可以根据方法名知其功能
  • 看似不相关的方法最终调用的是同一个方法,