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. [MtOI2019]幽灵乐团

    题目 一个很暴力的辣鸡做法 考虑到两个数的\(\gcd\)是所有质数次幂取\(\min\),两个数的\(\rm lcm\)是所有质数次幂取\(\max\),于是最后的答案一定是\(\prod p_i^ ...

  2. 004-Java进制转换

    整型数据共有4中进制形式 二进制(binary):以0b或者0B开头 十进制(decimal) 八进制(octal):以数字0开头 十六进制(hex):以0x或者0X开头 二进制数据包含原码反码和补码 ...

  3. 透彻理解并掌握JavaScript的this

    前言 无论是JavaScript新手还是老手,JavaScript中的this关键词可能都会令你困惑.本文旨在透彻地阐述this.读完本文,就再也不用怕JavaScript中的this了.你将会知道在 ...

  4. scala中ArrayBuffer简单使用

    import scala.collection.mutable.ArrayBuffer /** * 与Array区别: * 1.Array是不可变的,不能直接地对其元素进行删除操作,只能通过重赋值或过 ...

  5. Ubuntu下github pages+hexo搭建自己的博客

    hexo 是一个基于Node.js的静态博客程序,可以方便的生成静态网页托管在github上.Hexo简单优雅, 而且风格多变, 适合搭建个人博客,而且支持多平台的搭建. 平台 Ubuntu14.04 ...

  6. MFC文档视图结构学习笔记

    文档/视图概述 为了统一和简化数据处理方法,Microsoft公司在MFC中提出了文档/视图结构的概念,其产品Word就是典型的文档/视图结构应用程序 MFC通过其文档类和视图类提供了大量有关数据处理 ...

  7. mysql做主从配置

    最近想对公司的数据库做个从数据库,除了每天定时备份外,再多出一个同步数据库,双保险,这样也可以用从数据库就行比较耗资源的数据统计. 技术手段最好能记住,然后就是做笔记了,但是每次都查笔记也不好,希望能 ...

  8. JavaScript中纯JS写21点游戏

    // 21点游戏 分为人机对战和人人对战 // 玩家每次抽一张牌 牌的点数为1-10点随机数 谁更接近21点谁就获胜 let readline = require("readline-syn ...

  9. 扩展gcd求逆元

    当模数为素数时可以用费马小定理求逆元. 模数为合数时,费马小定理大部分情况下失效,此时,只有与模数互质的数才有逆元(满足费马小定理的合数叫伪素数,讨论这个问题就需要新开一个博客了). (对于一个数n, ...

  10. 使用WebStorm上传本地项目到GitHub和GitLab

    在使用 WebStorm 上传本地项目到 GitHub 之前,先要做一些相关配置. 首先打开 WebStorm ,依次点击File -> Settings… 打开系统设置面板,在上面搜索 git ...