public final class String
implements java.io.Serializable, Comparable<String>, CharSequence  String被final修饰,表示String类不能被继承。
 String类实现了Serializable、Comparable、CharSequence接口。
 /** The value is used for character storage. 字符串是以字符数组的形式存储的*/
private final char value[]; /** Cache the hash code for the string */
private int hash; // Default to 0
equals方法:
 1 /**
2 * 将此字符串与指定对象进行比较,如果内容相同,则判定它们相同
3 *
4 * @param anObject 指定的对象
5 * The object to compare this {@code String} against
6 *
7 * @return 如果两个字符串相等(只要字符串的内容相等就算相等),则返回true,否则返回false.
8 *
9 * @see #compareTo(String) str1.equals(anObject) str2表示指定的对象,str1表示要比较的字符串
10 * @see #equalsIgnoreCase(String)
11 */
12 public boolean equals(Object anObject) {
13 //如果这两个对象相等,直接返回true。因为==相等表示地址相同,字符串的内容也相同。
14 if (this == anObject) {
15 return true;
16 }
17 //如果anObject是字符串类型的
18 if (anObject instanceof String) {
19 //强转为String类型
20 String anotherString = (String) anObject;
21 //获取要比较的字符串的长度
22 int n = value.length;
23 //如果要比较的字符串长度 和 被比较的对象的字符串长度相同,再进行继续比较
24 if (n == anotherString.value.length) {
25 char v1[] = value;//将要比较的字符串转成char[]数组
26 char v2[] = anotherString.value;//将被比较的对象转成char[]数组
27 int i = 0;
28 //两个数组中的索引相同的字符是否都相同,只要有一个不相同,就返回false
29 //char类型的数据进行比较的时候,会进行类型提升,提升为int类型进行比较
30 while (n-- != 0) {
31 if (v1[i] != v2[i])
32 return false;
33 i++;
34 }
35 return true;
36 }
37 }
38 return false;
39 }
在String中的equals方法中会先判断两个对象的内存地址是否相等,如果相等,那么equals就return true,如果不相等,则会进一步判断传过来的对象是不是字符串类型的,如果是则将两个字符串对象char数组,然后一个一个字符的比较,如果都相等,则返回true。

startsWith方法:
 1    /**
2 * Tests if the substring of this string beginning at the
3 * specified index starts with the specified prefix.
4 *
5 * 测试源字符串是否从索引toffset处开始以字符串prefix开始
6 * @param prefix 前缀.
7 * @param toffset 索引 where to begin looking in this string.
8 * @return {@code true} if the character sequence represented by the
9 * argument is a prefix of the substring of this object starting
10 * at index {@code toffset}; {@code false} otherwise.
11 * The result is {@code false} if {@code toffset} is
12 * negative or greater than the length of this
13 * {@code String} object; otherwise the result is the same
14 * as the result of the expression
15 * <pre>
16 * this.substring(toffset).startsWith(prefix)
17 * </pre>
18 */
19 public boolean startsWith(String prefix, int toffset) {
20 char ta[] = value;//源字符串转成字符数组
21 int to = toffset;
22 char pa[] = prefix.value;//某个字符串prefix转成字符数组
23 int po = 0;
24 int pc = prefix.value.length;//某个字符串的长度
25 // 索引的值不能小于0 也不能大于(源字符串长度-某个字符串prefix的长度),就是为了不让索引越界。
26 if ((toffset < 0) || (toffset > value.length - pc)) {
27 return false;
28 }
29
30 //将源字符串转成的字符数组的索引在toffset处开始 与 某个字符串prefix转成的字符数组在索引在0处开始比较
31 while (--pc >= 0) {
32 //如果字符有不相同的,直接返回false
33 if (ta[to++] != pa[po++]) {
34 return false;
35 }
36 }
37 return true;
38 }
39
40 /**
41 * 测试源字符串是否以某个字符串prefix开始
42 *
43 * @param prefix 某个字符串prefix.
44 * @return true:表示源字符串以prefix;false:表示源字符串不是以prefix开始;
45 * @since 1. 0
46 */
47 public boolean startsWith(String prefix) {
48 return startsWith(prefix, 0);
49 }
endsWith方法:
 1  /**
2 * 测试源字符串是否以某个字符串suffix结尾
3 *
4 * @param suffix 后缀.
5 * @return true:表示源字符串以suffix结尾;false:表示源字符串不是以suffix结尾;
6 */
7 public boolean endsWith(String suffix) {
8 /**
9 * 本质是调用startsWith方法,方法中的第二个参数就是用于计算出应该从哪个位置开始比较的索引
10 */
11 return startsWith(suffix, value.length - suffix.value.length);
12 }

replace方法:
 1 /**
2 * Returns a string resulting from replacing all occurrences of
3 * {@code oldChar} in this string with {@code newChar}.
4 * <p>
5 * If the character {@code oldChar} does not occur in the
6 * character sequence represented by this {@code String} object,
7 * then a reference to this {@code String} object is returned.
8 * Otherwise, a {@code String} object is returned that
9 * represents a character sequence identical to the character sequence
10 * represented by this {@code String} object, except that every
11 * occurrence of {@code oldChar} is replaced by an occurrence
12 * of {@code newChar}.
13 * <p>
14 * Examples:
15 * <blockquote><pre>
16 * "mesquite in your cellar".replace('e', 'o')
17 * returns "mosquito in your collar"
18 * "the war of baronets".replace('r', 'y')
19 * returns "the way of bayonets"
20 * "sparring with a purple porpoise".replace('p', 't')
21 * returns "starring with a turtle tortoise"
22 * "JonL".replace('q', 'x') returns "JonL" (no change)
23 * </pre></blockquote>
24 *
25 * @param oldChar 要被替换的字符(源字符串中的要被替换的字符)(注意,会将源字符串中所有等于oldChar的字符替换成newChar字符)
26 * @param newChar 用来替换的新字符
27 * @return 返回替换后的字符串 a string derived from this string by replacing every
28 * occurrence of {@code oldChar} with {@code newChar}.
29 */
30 public String replace(char oldChar, char newChar) {
31 //如果老字符 和 新字符不相等
32 if (oldChar != newChar) {
33 int len = value.length;//获取源字符串的长度
34 int i = -1;
35 char[] val = value; //将源字符串用字符数组的形式表现 我称它为源字符数组
36
37 //找出要被替换的字符,获取到索引i,源字符数组中第i个元素要替换成字符newChar. 注意,这里只找第一个和oldChar相等的字符的索引。
38 while (++i < len) {
39 if (val[i] == oldChar) {
40 break;
41 }
42 }
43
44 //如果索引小于源字符串长度,也就是索引没有越界
45 if (i < len) {
46 //把源字符数组中的数据在索引 [0~i-1] 范围的复制到 一个新的字符数组中
47 char buf[] = new char[len];
48 for (int j = 0; j < i; j++) {
49 buf[j] = val[j];
50 }
51 //对索引在[i,length-1] 范围的进行操作
52 while (i < len) {
53 //获取索引i处的元素的值
54 char c = val[i];
55 //判断源字符串中第i个元素是否和oldChar相等,如果相等,就替换成newChar,否则还是存源字符串在索引i处的元素
56 buf[i] = (c == oldChar) ? newChar : c;
57 i++;
58 }
59 return new String(buf, true);//将替换后的字符数组转成字符串并返回
60 }
61 }
62 return this;//如果oldChar和newChar相同,就把源字符串原封不动的返回
63 }

JDK源码阅读--String的更多相关文章

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

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

  2. JDK源码阅读(一):Object源码分析

    最近经过某大佬的建议准备阅读一下JDK的源码来提升一下自己 所以开始写JDK源码分析的文章 阅读JDK版本为1.8 目录 Object结构图 构造器 equals 方法 getClass 方法 has ...

  3. 利用IDEA搭建JDK源码阅读环境

    利用IDEA搭建JDK源码阅读环境 首先新建一个java基础项目 基础目录 source 源码 test 测试源码和入口 准备JDK源码 下图框起来的路径就是jdk的储存位置 打开jdk目录,找到sr ...

  4. JDK源码阅读-FileOutputStream

    本文转载自JDK源码阅读-FileOutputStream 导语 FileOutputStream用户打开文件并获取输出流. 打开文件 public FileOutputStream(File fil ...

  5. JDK源码阅读-FileInputStream

    本文转载自JDK源码阅读-FileInputStream 导语 FileIntputStream用于打开一个文件并获取输入流. 打开文件 我们来看看FileIntputStream打开文件时,做了什么 ...

  6. JDK源码阅读-RandomAccessFile

    本文转载自JDK源码阅读-RandomAccessFile 导语 FileInputStream只能用于读取文件,FileOutputStream只能用于写入文件,而对于同时读取文件,并且需要随意移动 ...

  7. JDK源码阅读-FileDescriptor

    本文转载自JDK源码阅读-FileDescriptor 导语 操作系统使用文件描述符来指代一个打开的文件,对文件的读写操作,都需要文件描述符作为参数.Java虽然在设计上使用了抽象程度更高的流来作为文 ...

  8. JDK源码阅读-Reference

    本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果 ...

  9. JDK源码阅读-DirectByteBuffer

    本文转载自JDK源码阅读-DirectByteBuffer 导语 在文章JDK源码阅读-ByteBuffer中,我们学习了ByteBuffer的设计.但是他是一个抽象类,真正的实现分为两类:HeapB ...

随机推荐

  1. 网页开发人员收藏的16款HTML5工具

    本文收集的20款优秀的 HTML5 Web 应用程序,值得添加到您的 HTML5 的工具箱中,他们能够帮助你开发前端项目更快.更容易. Initializr Initializr 是一个可以让你创建 ...

  2. pytorch,cuda8,torch.cuda.is_available return flase (ubuntu14)

    因为ubuntu 系统是14.0的,安装pytorch1.0的时候,本身已经安装好了cuda8,在验证gpu的时候,torch.cuda.is_available()返回false 安装命令是: co ...

  3. 多个for循环使用

    for循环 例子 语法 vue.js的for循环 <div id="myfor"><li v-for="student in studentList&q ...

  4. 前端常用的库和实用技术之JavaScript 模块化

    模块化概念 AMD是requirejs在推广过程中对模块化定义的规范化产出. 异步加载模块,依赖前置,提前执行 Define定义模块define(['require','foo'],function( ...

  5. CSS动画库——animate.css的使用

    Animate.css是一款强大的CSS3动画库 官网地址:https://daneden.github.io/animate.css/ 使用方法如下所示: (1)下载animate.css 下载地址 ...

  6. vue 项目 去哪儿

    去哪儿项目 使用vue +vue-router+vuex +axios完成,包括3个部分内容 1.首页演示,包括首页header,首页轮播图,周末去哪儿,热销推荐开发 2.城市列表页面开发 ,包括城市 ...

  7. python读文件判断是否已到EOF

    python读文件判断是否已到EOF,也即结尾,一般其它语言都是以EOF直接来判断的,比如 if ( fp.read(chunk_size) == EOF), 但python到结尾后是返回空字符串的, ...

  8. CSIC_716_20191106【列表、元组、字典、集合】

    python的数据类型及其内置方法 一.列表(续) list.count( ).list.index( ) list = ['1', '2', '3', '2', 'a', 'b', 'c', 'a' ...

  9. Postgraduate

    https://account.chsi.com.cn/passport/login?entrytype=yzgr&service=https%3A%2F%2Fyz.chsi.com.cn%2 ...

  10. leetcode-219-存在重复元素②

    题目描述: 第一次提交:超时 class Solution: def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool ...