JDK源码学习系列01----String

写在最前面:

这是我JDK源码学习系列的第一篇博文,我知道源码学习这条路很难坚持,但是我始终相信,不积跬步无以至千里。当然啦,兴趣和方法可以让这条路变得很是happy。初步计划是每天早上晨会前看一个类的源码,因为还在实习初期,所以任务不是那么滴繁重,更何况,时间就像那个,挤挤总是有的嘛~~晚上回来写写博文,一是加深理解二来也加深记忆方便以后查阅。学习的步骤当然是先从自己已经用的非常熟练的类入手。

期待这一路的繁花盛景,哈哈~~~

java.lang.String

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence

String 是静态类,不可以被继承,可以被序列化,实现了Comparable接口

1.成员变量

private final char value[];
private final char value[];
private final int offset;//偏移量
private final int count;
private int hash;

String是以字符数组的形式实现的,变量定义为final,说明String一旦初始化后就不可变,这也是与StringBuffer的最大区别。

2.构造函数

3.常用方法

1.char charAt(int index)

源码很简单,注意参数的判断,养成编程的好习惯,注意细节。

public char charAt(int index) {
if ((index < 0) || (index >= count)) {//养成好习惯,参数的判断!
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}

2.boolean equals(Object anObject)

原本传入的参数是object型,惭愧自己平时连这个都没有注意,因为源码中已经对问题进行了处理。个人绝对源码中的while(n--!=0)以及if(v1[i++]!=v2[j++])写的很好啊,让总是for的我掩面而过啊~~学习源码的编程风格~

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;//注意细节,向下转型
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {//这里写得太精妙了!~~
if (v1[i++] != v2[j++])//点32个赞~~
return false;
}
return true;
}
}
return false;
}

3.boolean equalsIgnoreCase(String anotherString)

此源码用于时刻提醒自己,能用 x>y?a:b解决的情况就坚决不要去写if else之类的!!

 public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true :
(anotherString != null) && (anotherString.count == count) &&
regionMatches(true, 0, anotherString, 0, count);
}

4.boolean startsWith(String prefix, int toffset)

注意,第一个参数是String而不是char,哈哈,

public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = offset + toffset;
char pa[] = prefix.value;
int po = prefix.offset;
int pc = prefix.count;
if ((toffset < 0) || (toffset > count - pc)) {//时刻记得参数的考虑
return false;
}
while (--pc >= 0) {//风格和上面提到的一样~自己写时注意--pc和pc--,还要注意代表的是长度还是下标
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}

5.boolean endsWith(String suffix)

这个方法写的简直是大爱啊~~~代码的重用思想也用的很好

public boolean endsWith(String suffix) {
return startsWith(suffix, count - suffix.count);
}

6.String replace(char oldChar, char newChar)

注意,replace参数是char,源码思路是找到第一个出现的oldChar,如果oldChar的下标小于len的下标,把oldChar前面的存到临时变量buf中,把oldChar后面的所有oldChar都变为newChar.

public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = count;
int i = -1;
char[] val = value;
int off = offset; while (++i < len) {//!!!学习源码编程风格
if (val[off + i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0 ; j < i ; j++) {
buf[j] = val[off+j];
}
while (i < len) {//!!!!!!!!!!
char c = val[off + i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(0, len, buf);
}
}
return this;
}

7.int compareTo(String anotherString)

public int compareTo(String anotherString) {
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset; if (i == j) {
int k = i;
int lim = n + i;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {//一旦不等就reurn
return c1 - c2;
}
k++;
}
} else {
while (n-- != 0) {//漂亮的代码
char c1 = v1[i++];
char c2 = v2[j++];
if (c1 != c2) {
return c1 - c2;
}
}
}
return len1 - len2;
}

8.int compareToIgnoreCase(String str)

此方法采用的是自定义比较器来实现忽略字母大小的比较,比较器类CaseInsensitiveComparator实现了Comparator和Serializable接口。

public int compareToIgnoreCase(String str) {
return CASE_INSENSITIVE_ORDER.compare(this, str);
}
 public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8575799808933029326L; public int compare(String s1, String s2) {
int n1=s1.length(), n2=s2.length();
for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
char c1 = s1.charAt(i1);
char c2 = s2.charAt(i2);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
return c1 - c2;
}
}
}
}
return n1 - n2;
}
}

9.String valueOf(Object obj)

将object转换为String,比obj+""和obj.toString()都好,因为从源码中可以看出,valueOf()很好的避免了空指针异常。

 public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

10.int lastIndexOf(String str, int fromIndex)

对于子串的定位or匹配,若能匹配,返回匹配开始的第一个下标;若是匹配失败则返回-1.

public int lastIndexOf(String str, int fromIndex) {
return lastIndexOf(value, offset, count,
str.value, str.offset, str.count, fromIndex);
}
static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
/*
* Check arguments; return immediately where possible. For
* consistency, don't check for null str.
*/
int rightIndex = sourceCount - targetCount;
if (fromIndex < 0) {
return -1;
}
if (fromIndex > rightIndex) {
fromIndex = rightIndex;
}
/* Empty string always matches. */
if (targetCount == 0) {
return fromIndex;
} int strLastIndex = targetOffset + targetCount - 1;
char strLastChar = target[strLastIndex];
int min = sourceOffset + targetCount - 1;
int i = min + fromIndex; startSearchForLastChar:
while (true) {
while (i >= min && source[i] != strLastChar) {
i--;
}
if (i < min) {
return -1;
}
int j = i - 1;
int start = j - (targetCount - 1);
int k = strLastIndex - 1; while (j > start) {
if (source[j--] != target[k--]) {
i--;
continue startSearchForLastChar;
}
}
return start - sourceOffset + 1;
}
}

11.boolean contains(CharSequence s)

对于CharSequence,是一个接口,String实现了这个接口。其实这个方法传入的参数就是字符串,那为什么不直接以String作为参数呢,因为此处还可以是StringBuffer和StringBuilder等。此方法用于检查是否包含子串,作用上和indexOf类似,从源码可以看出,contains实际上就是调用了indexOf方法。

public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}

JDK源码学习系列01----String的更多相关文章

  1. JDK源码学习系列03----StringBuffer+StringBuilder

                         JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...

  2. JDK源码学习系列02----AbstractStringBuilder

     JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...

  3. JDK源码学习系列05----LinkedList

                                             JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...

  4. JDK源码学习系列04----ArrayList

                                                                             JDK源码学习系列04----ArrayList 1. ...

  5. JDK源码学习--String篇(二) 关于String采用final修饰的思考

    JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JD ...

  6. JDK源码学习笔记——Integer

    一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...

  7. SpringBoot源码学习系列之异常处理自动配置

    SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...

  8. SpringBoot源码学习系列之嵌入式Servlet容器

    目录 1.博客前言简单介绍 2.定制servlet容器 3.变换servlet容器 4.servlet容器启动原理 SpringBoot源码学习系列之嵌入式Servlet容器启动原理 @ 1.博客前言 ...

  9. Spring5.0源码学习系列之浅谈BeanFactory创建

    Spring5.0源码学习系列之浅谈BeanFactory创建过程 系列文章目录 提示:Spring源码学习专栏链接 @ 目录 系列文章目录 博客前言介绍 一.获取BeanFactory主流程 二.r ...

随机推荐

  1. POJ 3415 Max Sum of Max-K-sub-sequence (线段树+dp思想)

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  2. 一则简单演示样例看Oracle的“无私”健壮性

    Oracle的强大之处就在于他能总帮助让你选择正确的运行计划,即使你给了它错误的指示. 实验: 1. 创建測试表: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  3. VSTO 为Office已有右键菜单添加自己的菜单项(word,Excel)

    原文:VSTO 为Office已有右键菜单添加自己的菜单项(word,Excel) private void AddRightMenu()         {            Microsoft ...

  4. 用N2N搭建简单的VPN

    1.   概述 N2N是一款开源的P2P VPN软件,其作者是著名的开源网管软件ntop的作者Luca Deri. N2N是一个双层架构的VPN,它让用户能够在网络层上开发P2P应用的典型功能,而不是 ...

  5. Linux/UNIX之信号(2)

    信号(2) sigaction函数 sigaction函数的功能是检查或改动与制定信号相关联的处理动作.此函数代替了signal函数. #include <signal.h> int si ...

  6. HDU4876ZCC loves cards(多校题)

    ZCC loves cards Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tot ...

  7. hdu1505(dp求最大子矩阵)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1505 分析: 这题是HDU 1506 的加强版,定义一个二维数组,d[i][j]表示第i行j列元素在前 ...

  8. C++技术问题总结-第11篇 网络通信中主机序网络序

    网络通信常常涉及到字节序转化,接下来理解主机序和网络序有什么异同. ①主机字节顺序HBO(Host Byte Order) 採用小头序(little-endian),从低到高的顺序存储. 低位字节排放 ...

  9. Android---App Widget(一)

    本文译自:http://developer.android.com/guide/topics/appwidgets/index.html App Widgets是一些较小的应用程序窗口,它们能够被嵌入 ...

  10. 用XAML做网页!!—广告展示区

    原文:用XAML做网页!!-广告展示区 此次我们来进行广告展示区块的制作. 首先在Show区块中去掉原来设置的背景色,加入新的渐变背景设定: <Grid.Background> <L ...