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. <读书笔记>001-以解决问题为导向的python编程实践

    以解决问题为导向的python编程实践 0.第0章:计算机科学 思考:计算机科学是否为计算机编程的简称? 编程的困难点:1.同时做2件事(编程语言的语法.语义+利用其解决问题)  2.什么是好程序(解 ...

  2. redhat7和redhat6混合搭建文档

    1.下载cm对应redhat7的版本.2.修改/opt/cloudera/cm-5.10.0/etc/cloudera-scm-agent/config.ini成为中心机器hostname/ip(ma ...

  3. 2019-8-31-C#-如何写出一个不能被其他程序集继承的抽象类

    title author date CreateTime categories C# 如何写出一个不能被其他程序集继承的抽象类 lindexi 2019-08-31 16:55:58 +0800 20 ...

  4. PHP算法之按奇偶排序数组

    给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素. 你可以返回满足此条件的任何数组作为答案. 示例: 输入:[3,1,2,4]输出:[2,4,3,1]输出 ...

  5. Yii2 使用 npm 安装的包

    转载自: yii2.0.15 使用 npm 替换 bower,加速 composer 安装速度 [ 2.0 版本 ] 修改 ommon/config/main.php <?php return ...

  6. node---处理post请求

    //nodejs 处理post请求 // 异步 const http =require('http') const server=http.createServer((req,res)=>{ i ...

  7. 钉钉小程序----使用阿里的F2图表

    在钉钉小程序中使用F2的图表遇见很多问题 不能点击或者点击错乱的问题还没有解决,因为我解决不了........................... ------------------------- ...

  8. 廖雪峰Java16函数式编程-2Stream-5filter

    1.filter简介 Stream.filter()是一个转换方法,把一个Stream转换为另一个Stream. 所谓filter操作,就是对一个Stream的所有元素进行测试,不满足条件的元素就被过 ...

  9. LOIC Download

    { //https://github.com/NewEraCracker/LOIC }

  10. 2019亚太内容分发大会,阿里云获CDN领袖奖、技术突破奖

    近日,亚太CDN产业联盟主办的2019亚太内容分发大会在上海召开.本次大会以"5G分发"为主题,集结了CDN领域近千名行业领袖.专家参与.在会上,阿里云斩获“CDN领袖奖”.“技术 ...