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. 21个CSS技巧

    级联样式表(CSS)在当代Web设计中已经成为重要的环节,如果没有CSS现在的网站将像10年前一样不堪入目.随着CSS技术的普及,越来越多的高质量CSS教程涌入互联网,让我们的学习更加方便. 1.CS ...

  2. iOS开发系列-定时器强引用问题

    概述 iOS开发中常用的定时器NSTimer.CADisplayLink. NSTimer 和 CADisplayLink 基本使用 NSTimer的创建方法有两个scheduledTimerWith ...

  3. c结构体指针使用

    #include <stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Date { un ...

  4. ArcGIS Server 10.x查询管理用户名和修改管理员密码

    在x:\Program Files\ArcGIS\Server\tools\passwordreset下有个bat文件,用管理员用户运行它. PasswordReset -l PasswordRese ...

  5. MySQL基本命令脚本

    一.基本命令 1.启动服务 说明:以管理员身份运行cmd 格式:net start 服务名称 示例:net start mysql57 2.停止服务 说明:以管理员身份运行cmd 格式:net sto ...

  6. java中的break continue

    break语句 在任何循环语句的主体部分,均可用break控制循环的流程.break用于强行退出循环,不执行循环中剩余的语句.(break语句也在switch语句中使用) public class B ...

  7. 使用ajax怎么请求跨域资源

    1.ajax中添加“xhrFields”和“crossDomain”,如: $.ajax({ url: url, data: data, type: "post", xhrFiel ...

  8. 0922CSP-S模拟测试赛后总结

    连发三篇爆炸实录我的心态竟然还这么好…… 昨天题目的D2.稍难. 这也不是我连续拿倒数第一的理由. T1不会.赛时硬写了一个30分的三次方暴力.还有一个地方写挂了.如果不是数据足够水我就爆零了. 也就 ...

  9. 三模数NTT模板

    求两个多项式的卷积对任意数p取模 两个好记的FNT模数: 5*2^25+1 7*2^26+1 原根都为3 //Achen #include<algorithm> #include<i ...

  10. android GPS: code should explicitly check to see if permission is available

    转载的,感谢作者,由于我找了很久才找到这个解决方法,因此我自己再转一遍 原文链接 https://blog.csdn.net/qinwendou/article/details/77849048 if ...