JAVA源码学习(一)——String类
一、String类的不可变性
源码:
public final class String//final修饰类,不可继承
private final char value[];//String类实际返回值为final修饰的char数组,其对象内容
1、测试数组char数组能否代替字符串
public static void main(String[] args) {String str = "abc";char[] ch = {'a','b','c'};System.out.println(str);System.out.println(ch);}
结果:可替代
abc
abc
2、测试String类是否可变
public static void main(String[] args) {String str = "abc";String t1 = str;str = "ab";String t2 =str;//假如String可变,t1=t2,反之,t1!=t2System.out.println(t1==t2);}
public static void main(String[] args) {StringBuilder str = new StringBuilder("abc");StringBuilder t1 = str;StringBuilder t2 =str.append("d");//假如String可变,t1=t2,反之,t1!=t2System.out.println(t1==t2);}
结果:不可变
false
true
二、String类常用构造
源码:
public String() {this.value = "".value;}public String(String original) {this.value = original.value;this.hash = original.hash;}public String(char value[]) {this.value = Arrays.copyOf(value, value.length);}
1、为何采用Arrays.copyof而非直接用this.value=value
传递的value为可变对象,将this.value指向它时,则this.value失去不可变性,而Arrays.copyof采用浅复制,保留了this.value的不可变性
2、源码复制过来一堆错?
。。。。源码中很多东西,你是没有使用权限的
三、String类常用方法
源码:
1、length()获取字符串长度
//其实就是获取char数组元素个数
public int length() {return value.length;}
2、isEmpty()判断是否为空
//假如字符串为null,则无法使用
public boolean isEmpty() {return value.length == 0;}
3、charAt(int i)获取指定位置字符
//返回字符数组指定元素
public char charAt(int index) {if ((index < 0) || (index >= value.length)) {throw new StringIndexOutOfBoundsException(index);}return value[index];}
4、equals(Object o )比较是否与指定对象内容相同
//如果是字符串,则挨个比较字符数组内容是否都相同
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}
*equalsIgnoreCase(String str)忽略大小写比较
//这里不是很明白,为何要比较两次,全大写或全小写,在我看都能实现目的if (ignoreCase) {char u1 = Character.toUpperCase(c1);char u2 = Character.toUpperCase(c2);if (u1 == u2) {continue;} if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {continue;}}
5、compareTo(String s)按字典顺序比较字符串
//长度不一样,返回长度差,字符不一样,返回字符顺序差,完全一致,返回0public int compareTo(String anotherString) {int len1 = value.length;int len2 = anotherString.value.length;int lim = Math.min(len1, len2);char v1[] = value;char v2[] = anotherString.value;int k = 0;while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;}return len1 - len2;}
6、startsWith(String s,int i) 判断字符是否从指定位置以指定字符串开始
public boolean startsWith(String prefix, int toffset) {char ta[] = value;int to = toffset;char pa[] = prefix.value;int po = 0;int pc = prefix.value.length;// Note: toffset might be near -1>>>1.if ((toffset < 0) || (toffset > value.length - pc)) {return false;}while (--pc >= 0) {if (ta[to++] != pa[po++]) {return false;}}return true;}
7、subString(int from,int end)按指定位置截取字符串
//其实就是按位复制字符数组
public String substring(int beginIndex, int endIndex) {if (beginIndex < 0) {throw new StringIndexOutOfBoundsException(beginIndex);}if (endIndex > value.length) {throw new StringIndexOutOfBoundsException(endIndex);}int subLen = endIndex - beginIndex;if (subLen < 0) {throw new StringIndexOutOfBoundsException(subLen);}return ((beginIndex == 0) && (endIndex == value.length)) ? this: new String(value, beginIndex, subLen);}
8、replace(char old,char new)将字符串中全部old字符替换为new
public String replace(char oldChar, char newChar) {if (oldChar != newChar) {int len = value.length;int i = -1;char[] val = value; /* avoid getfield opcode */
//如果不存在想被替换字符,则 i =lenwhile (++i < len) {if (val[i] == oldChar) {break;}}if (i < len) {char buf[] = new char[len];
//填充元素至中间数组for (int j = 0; j < i; j++) {buf[j] = val[j];}while (i < len) {char c = val[i];buf[i] = (c == oldChar) ? newChar : c;i++;}return new String(buf, true);}}return this;}
9、contains(String str)字符串中是否还有str子字符串
//借用indexOf,如果存在则得到正数
public boolean contains(CharSequence s) {return indexOf(s.toString()) > -1;}
10、matches(String regex)字符串是否满足正则匹配
public boolean matches(String regex) {return Pattern.matches(regex, this);}
11、replaceAll(String regex,String ele)按正则替换
public String replaceAll(String regex, String replacement) {return Pattern.compile(regex).matcher(this).replaceAll(replacement);}
12、split(String regex,int limit)按正则拆分字符串,获取指定个数的字符串数组
public String[] split(String regex, int limit) {char ch = 0;if (((regex.value.length == 1 &&".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||(regex.length() == 2 &®ex.charAt(0) == '\\' &&(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&((ch-'a')|('z'-ch)) < 0 &&((ch-'A')|('Z'-ch)) < 0)) &&(ch < Character.MIN_HIGH_SURROGATE ||ch > Character.MAX_LOW_SURROGATE)){int off = 0;int next = 0;boolean limited = limit > 0;ArrayList<String> list = new ArrayList<>();while ((next = indexOf(ch, off)) != -1) {
//获取未到limit个数,操作继续if (!limited || list.size() < limit - 1) {list.add(substring(off, next));off = next + 1;} else { // last one//assert (list.size() == limit - 1);list.add(substring(off, value.length));off = value.length;break;}}// If no match was found, return thisif (off == 0)return new String[]{this};// Add remaining segmentif (!limited || list.size() < limit)list.add(substring(off, value.length));// Construct resultint resultSize = list.size();if (limit == 0) {while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {resultSize--;}}String[] result = new String[resultSize];return list.subList(0, resultSize).toArray(result);}return Pattern.compile(regex).split(this, limit);}
13、toCharArray()将字符串还原为字符数组
public char[] toCharArray() {
//类初始化顺序导致该方法无法使用// Cannot use Arrays.copyOf because of class initialization order issueschar result[] = new char[value.length];System.arraycopy(value, 0, result, 0, value.length);return result;}
14、valueOf(Object o)
//如果字符数组或字符则用构造方法,如果是布尔类型,则返回true or false,如果是其他基本数据类型则用包装类的toString,public static String valueOf(Object obj) {return (obj == null) ? "null" : obj.toString();}
public static String valueOf(char c) {char data[] = {c};return new String(data, true);}
public static String valueOf(int i) {return Integer.toString(i);}
public static String valueOf(boolean b) {return b ? "true" : "false";}
14、format(String format ,Object...params)格式化字符串
public static String format(String format, Object... args) {return new Formatter().format(format, args).toString();}
四、正则表达式
字符
c 字符c
\unnnn, \xnn,\0n, \0nn, \0nnn 带有十六或八进制值的代码单元
\0n 八进制0n代表的字符(0<=n<=7)
\0nn 八进制0nn代表的字符(0<=n<=7)
\0mnn 八进制0mnn代表的字符(0<=m<=3,0<=n<=7)
\xnn 十六进制 0xnn所代表的字符
\uhhhh 十六进制 0xhhhh所代表的字符
\t, \n, \r, \f,\a, \e控制字符,依次是制表符,换行符,回车符,换页符,报警符和转义符
\cc 控制字符中出现的相应字符c
字符类
[C1C2. . .] C1、C2……中的任何字符。Ci可以是字符,字符范围(C1-C2)或者字符类。
[^. . .] 字符类的补集
[ . . .&& . . .] 两个字符类的交集
预定义字符类
. 除行终止符外的任何字符(如果DOTALL标志置位,则表示任何字符)
\d 数字[0-9]
\D 非数字[^0-9]
\s 空白字符[\t\n\r\f\x0B]
\S 非空白字符
\w 单词字符[a-zA-Z0-9_]
\W 非单词字符
\p{name} 一个指定的字符类,见表12-9
\P{name} 指定字符类的补集
边界匹配符
^ 和$ 输入的开头和结尾(在多行模式(multilinemode)下是行的开头和结尾)
\b 单词边界
\B 非单词边界
\A 输入的开头
\z 输入的结尾
\Z 除最后行终止符之外的输入结尾
\G 上个匹配的结尾
量词
X? 可选的X(即X可能出现,也可能不出现)
X* X,可以重复0次或多次
X+ X,可以重复1次或多次
X{n} X{n,}X{n,m} X重复n次,至少重复n次,重复n到m次
量词后缀(表达式所有量词都要加)
? 设默认(贪婪)匹配为reluctant(勉强)匹配
+ 设默认(贪婪)匹配为possessive(强制)匹配
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
。z~~z~~ 深夜1.11完稿。。。。。。。睡觉走起。。。
JAVA源码学习(一)——String类相关推荐
- java源码详解——String类
java源码详解--String类目录: Java String 类 下面开始介绍主要方法: Java charAt() 方法 Java compareTo() 方法 int compareTo(St ...
- Java 源码学习(String)
一.String 简介 public final class String implements java.io.Serializable, Comparable<String>, Cha ...
- JDK11源码学习05 | HashMap类
JDK11源码学习05 | HashMap类 JDK11源码学习01 | Map接口 JDK11源码学习02 | AbstractMap抽象类 JDK11源码学习03 | Serializable接口 ...
- Java源码阅读之String(4)
Java源码阅读之String(4) 这一篇博客主要阅读String类的查找和替换相关的方法. /**查询当前对象的哈希码,如果当前对象没有计算过哈希码*则计算当前对象的哈希码并赋值给当前对象的has ...
- Java 源码学习系列(三)——Integer
Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的字段. 此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还 ...
- Java源码学习笔记之lang包——包装类Integer.class
前言:仅为学习所发现而记录. JDK 版本:1.8 同样的,在去除所有方法和静态变量之后,以下为核心内容. public final class Integer extends Number impl ...
- JAVA源码学习--String
最近发四重新学习java的基础,从基本类型以及里面的各种方法开始看起,看的一本书<JAVA核心技术卷1,基础知识>,这是第十版,讲的JDK8的一些特性. 我在想我们创建对象的时候都是这样进 ...
- JDK源码学习笔记——String
1.学习jdk源码,从以下几个方面入手: 类定义(继承,实现接口等) 全局变量 方法 内部类 2.hashCode private int hash; public int hashCode() {i ...
- Java源码学习--00源码目录介绍
源码目录中的 rj.jar就是我们需要学习的源码所在目录,打开后发现有,com,java,javax,jdk,org,sun等不同的包 我们学习源码肯定需要排除干扰,如com,jdk,sun,or ...
最新文章
- 对于mysql存储过程感想_存储过程学习心得
- 数据结构 — B+ 树
- mysql 错误1136_mysql,_MySQL错误:Error Code: 1136,mysql - phpStudy
- pycharm安装lxml
- python线程状态_Python线程
- 如何夺回Windows 10系统权限?一分钟就够
- QT SQL使用指南
- bzoj 3209: 花神的数论题 喵哈哈村的秘境探险(四)
- Python- 索引 B+数 比如书的目录
- 第一、二章 引论、算法分析
- Win11快捷键大全
- 专用计算机国产化替代工作方案,倪光南再谈核心技术自主可控 列举国产替代方案...
- mysql,sqlserver查询表所有字段名
- XV6 - bootsect.S
- 我的推荐系统学习之路
- MenuetOS-令人不可思议的64位操作系统!-第二辑
- montypython买火柴_python nltk 笔记(持续更新)
- c语言程序设计需要学多久,九江c语言编程学习,九江学c语言编程报班,九江学c语言编程一般要多久才能学会...
- ttl低电平接大电阻_电路中上拉、下拉电阻的作用及原理
- 实用健指操:让你告别鼠标手、键盘手