JDK源码阅读--String
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 }
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的更多相关文章
- JDK源码学习--String篇(二) 关于String采用final修饰的思考
JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JD ...
- JDK源码阅读(一):Object源码分析
最近经过某大佬的建议准备阅读一下JDK的源码来提升一下自己 所以开始写JDK源码分析的文章 阅读JDK版本为1.8 目录 Object结构图 构造器 equals 方法 getClass 方法 has ...
- 利用IDEA搭建JDK源码阅读环境
利用IDEA搭建JDK源码阅读环境 首先新建一个java基础项目 基础目录 source 源码 test 测试源码和入口 准备JDK源码 下图框起来的路径就是jdk的储存位置 打开jdk目录,找到sr ...
- JDK源码阅读-FileOutputStream
本文转载自JDK源码阅读-FileOutputStream 导语 FileOutputStream用户打开文件并获取输出流. 打开文件 public FileOutputStream(File fil ...
- JDK源码阅读-FileInputStream
本文转载自JDK源码阅读-FileInputStream 导语 FileIntputStream用于打开一个文件并获取输入流. 打开文件 我们来看看FileIntputStream打开文件时,做了什么 ...
- JDK源码阅读-RandomAccessFile
本文转载自JDK源码阅读-RandomAccessFile 导语 FileInputStream只能用于读取文件,FileOutputStream只能用于写入文件,而对于同时读取文件,并且需要随意移动 ...
- JDK源码阅读-FileDescriptor
本文转载自JDK源码阅读-FileDescriptor 导语 操作系统使用文件描述符来指代一个打开的文件,对文件的读写操作,都需要文件描述符作为参数.Java虽然在设计上使用了抽象程度更高的流来作为文 ...
- JDK源码阅读-Reference
本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果 ...
- JDK源码阅读-DirectByteBuffer
本文转载自JDK源码阅读-DirectByteBuffer 导语 在文章JDK源码阅读-ByteBuffer中,我们学习了ByteBuffer的设计.但是他是一个抽象类,真正的实现分为两类:HeapB ...
随机推荐
- neo4j数据库迁移---------Neo4j数据库导入导出的方法
Neo4j数据进行备份.还原.迁移的操作时,首先要关闭neo4j; /usr/share/neo4j/bin neo4j stop 如果出现 Neo4j not running 出现这种情况, Neo ...
- WebApi 如何 优雅的 对 输入输出 解密加密
原文:WebApi 如何 优雅的 对 输入输出 解密加密 这不是变态的想法, 这只是对现实需求的转化. 因为有密文, 所以本文不适用于浏览器到服务端的数据交换; 只适用于服务端到服务端的数据传输. 用 ...
- TwainCapabilities
Twain Capabilities 2013年10月15日 ⁄ 综合 ⁄ 共 6098字 ⁄ 字号 小 中 大 ⁄ 评论关闭 转自:http://blog.163.com/lvan100@yeah/ ...
- ASP.NET 页面的生命周期
本文转载自清风飘过的博客,地址:http://www.cnblogs.com/couhujia/archive/2010/04/23/1718405.html 页面生命期分三个阶段:建立阶段,回发阶段 ...
- 使用Element的upload上传组件,不使用action属性上传
1.需要实现的效果如下图,在点击提交的时候再提交file数据,和其他数据统一上传,我把file转换成了base64的格式,可以再上传之前显示缩略图 2.代码分析 action属性值为"#&q ...
- [JZOJ6271] 2019.8.4【NOIP提高组A】锻造
题目 题目大意 武器的每个级别有固定的两种属性\(b_i\)和\(c_i\) 可以用\(a\)的代价得到一把\(0\)级的武器. 可以将\(x\)级武器和\(y=\max(x-1,0)\)级武器融合锻 ...
- 共享商业&技术红利,阿里云SaaS加速器让天下没有难做的SaaS
9月26日,阿里云在2019杭州云栖大会上发布了SaaS加速器3.0版“一云多端”多个应用平台,展示了阿里云给伙伴带来的多种商业和技术红利.阿里云SaaS加速器将帮助伙伴做好SaaS,卖好SaaS:帮 ...
- 最大流dicnic——hdu1532模板题
#include<bits/stdc++.h> using namespace std; #define maxn 1005 #define ll long long const ll i ...
- dp转图论——cf1070A好题
dp的状态转移很像一张有向图:每个状态为一个点,每中转移方案是一条有向边 本题要求是求出最小的数,那我们用状态[i,j]表示模i,数位和为j,那么从每个点出发的十条有向边代表[0,9]十个数 从每个状 ...
- 2428: [HAOI2006]均分数据
模拟退火.一种十分玄学的随机算法,网上可以查到比较详细的资料. 先随机地把数分成m组,每次随机地选择一个数,一开始直接选最小的一组,后来就随机一组,把这个数换到该组看看答案能不能变小,如果变小则换,如 ...