一.字符串的构造
1.使用常量串构造:
2.直接new String对象:
3.使用字符数组进行构造:
4.字符串类型的引用内存结构:(value是一个数组,数组是byte类型(JDK1.17)(在JDK1.8中是char类型),存储的是字符串每个字符的十进制,一个String类中的成员变量不止这些,这只是一部分)
5.计算字符串长度用变量名.length():
6.String是引用类型可以设置为null但是设置为null的时候无法计算长度。
7.当是空字符的时候才0:
8.isEmpty使用:(判断字符串是否为空,但是null不能使用)
9.null是没有这个引用,空字符串是有这个对象,是不过没有字符。
二.规定
只要是双引号 引起来的字符串常量,会存在一个字符串常量池中。
存在逻辑:
1.先检查这个内存(字符串常量池)有没有这个字符串。
2.如果没有,才会进行存储。
3.如果有,就不再重复存储,直接拿出使用。
三.字符串的比较
1.比较两个字符串是否相同就要用equals,相同返回true不同返回false:
2.比较两个字符串时是否相同时不看大小写可以用equalsIgnoreCase:
3.比较两个字符串的大小用compareTo:(通过第一个不相同的字符的ASCII来获得差值)。
4.比较两个字符串的大小不看大小写时用compareToIgnoreCase:
四.字符串的查找
其中一些字符串查找的方法:
1.charAt:
2.indexof(char ch):
3..indexof(char ch,fromIndex):
4..indexof(String str):
5.indexOf(String str, intfromIndex):
6.lastIndexOf(int ch):
7.lastIndexOf(int ch, intfromIndex):(没找到返回-1)
8.lastIndexOf(String str):
9.lastIndexOf(String str, intfromIndex):(当找到这个字符串的首字母的时候,如果后面相同就可以打印出来位置,即使这个方法是从后面往前找,但是后面的观察这个字符串与输入的字符串相同还是会返回这个字符串首字符的下标)
五.字符串的转换
1.将数字转换为字符串:
2.也可以对一个对象进行转换:
3.字符串转换为数字:
4.大小写的转换:(这里说明字符串的大小写变换不是在原来的字符串上面修改的)
5.字符串与数组之间的转换:
6.格式化:
7.String trim():去掉字符串中的左右空格,保留中间空格 :
六.字符串的替换
1.replace(old char,newchar):(字符的替换)
2.replace(target,replacement):(字符串的整体替换)
3.replaceFirst(regex,replacement):(第一个字符串的整体替换):
4.replaceAll也是字符串的整体替换:
七.字符串的拆分
1.String[] split(String regex):将字符串全部拆分
2.String[] split(String regex, int limit):将字符串以指定的格式,拆分为limit组
3.其中有一些特殊符号是没办法用来当作分隔符的,就需要使用//来转义:
4.多个分隔符可以用 | 来分隔:
5.多次拆分:
八.字符串的截取
1.String substring(int beginIndex) :(从指定索引截取到结尾):
2.String substring(int beginIndex, int endIndex) : 截取部分内容 :
需要注意的是这里1,3的范围是[1,3)!!!
九.字符串的不可变性
1.这里的final表明这个类不能被继承。
2.这里的final表示的是value里面的地址不能更改,但是value所指向的数组里面的内容是可以发生改变的。
3.这里的value是private修饰的,我们就无法拿到value引用,因为他被封装在String类中,其中也没有get和set方法。所以就造就了字符串的不可变性。
4.这里还需要解释一下,当我们用String s = "abcd";的时候需要创建一个新的对象去s = "ABCD";那么此时s是新的对象,其中的value是属于String类中的一个成员变量,如果new了一个新的对象那么这个value又会创建一个新的value,所以这里不是通过改变value中的值!!!
十.字符串的修改
这个简单的代码,至少又三个对象,但是她的底层是比较复杂的而且很浪费空间和时间。
底层:
上述第一张图的三行代码就需要底层中6行代码来实现,并且还需要实例化对象和调用方法,这些都需要空间和时间的,就比较的复杂。
所以减少字符串的拼接!需要字符串的拼接直接调用StringBuilder:
并且当我们看到第一张图代码如果是循环拼接的话那么他的反汇编就会不断重复的创建StringBuilder的对象,就增加了负担,我们第二张图就是直接将实例化对象提出来减少了重复创建对象:(goto 5 的意思就是循环)
StringBuilder和StringBuffer类 :他们的字符串内容都是可以修改的:
这是StringBuilder和StringBuffer类的部分方法:
这是StringBuilder和StringBuffer类的部分方法使用:
StringBuilder和StringBuffer类的区别:StringBuffer里面有一个关键字synchronized(同步)修饰的,这个关键字修饰之后就让这个StringBuffer类线程安全,类比上厕所,有人在上厕所的时候就会锁住,没人上厕所的时候就会解锁。StringBuffer就可以用来多线程,StringBuilder就是线程不安全的,用来单线程。根据不同场景来使用线程,不能一直用StringBuffer,毕竟开关锁都需要消耗时间的。
通过一个代码观察他们所用的时间: