文章目录
- 一、String类
- String的介绍
- String实例化
- 面试题:String s=new String("abc")创建对象,在内存中创建了几个对象?
- 易错题1
- 易错题2
- String常用方法
- String与char[ ]之间的转换
- String与byte[ ]之间的转换
- 二、StringBuffer类、StringBuilder类
- String、StringBuffer、StringBuilder的异同
- 问题1:StringBuffer数组长度
- 问题2:扩容
- StringBuffer类常用方法(StringBuilder同样适用)
- String、StringBuffer、StringBuilder的效率从高到低排列
一、String类
String的介绍
String:字符串,用“”引起来表示
1、String声明为final的,不可被继承
2、String实现了Serializable接口,表示字符串是支持序列化的
实现了Comparable接口,表示String可以比较大小
3、String内部定义了final char[ ] value,用于存储字符串数据,final代表数组不可以在被重新赋值,数组元素也不可被修改
4、String:代表一个不可变的字符序列(不可变性)
体现1:当对字符串重新赋值时,需要重新制定内存区域复制,不能在原有的内存区域赋值
体现2:当对现有的字符串进行连接操作时,也需要重新制定内存区域,不能在原有区域进行修改
体现3:当调用String的replace方法对指定字符串或字符进行修改时,也需要重新制定内存区域,不能在原有区域进行修改
5、通过字面量方式(区别于new方式)给一个字符串赋值,此时的字符串声明在字符串常量池中
6、字符串常量池中不会存储相同内容的字符串
过程描述:通过字面量的定义方式,新建了一个s1,内容为abc,新建了一个字符串s2,内容为abc,在s1内容没有改为hello之前,因为两个字符串存储的内容一样,所以两个字符串的地址值相同,即System.out.println(s1==s2);当s1内容变为hello时,因为字符串的不可变性,并不是将s1原有的存储区域中的内容abc改成hello,而是在内存中重新开辟一个区域,内容为hello,并让s1指向这个新的区域。此时s1内容变为hello,且s1和s2的地址值不再相同
String实例化
1、字面量定义(声明在方法取得字符串常量池中)
2、new+构造器定义(保存在堆空间中,地址值也是堆空间中的)
描述过程:s1和s2是通过字面量定义的,s3和s4是通过new的方式定义的,s1
=
=
==
==s2是true前面解释过了,下面几个判断是因为:s3和s4都在堆空间中开辟了新的存储区域,是String的两个实例化的对象,分别是两套内容,对应两个地址,所以s3
=
=
==
==s4是false;s1、s2中的地址值是方法区中的,s3、s4是堆空间中的,两者地址值肯定不相同,所以s1
=
=
==
==s4、s2
=
=
==
==s4都是false。但是两者之间也存在关系:他们中的内容是一样的,都是Java EE,体现在,s3、s4是String类型,有属性value,而value是引用变量,存储的内容是字符串,所以value的内容是存储的字符串的地址值。所以s1、s2在方法区中的地址值其实是保存在s3、s4的属性value中,类似于:
另:
是true的原因:相当于用字面量的方式给Person类中的属性name赋值,其中name是String类型的。
面试题:String s=new String(“abc”)创建对象,在内存中创建了几个对象?
两个,一个是new产生的堆空间中的,一个是char [ ]对应的常量池中的数据“abc”
易错题1
【总结】
1、常量和常量的拼接,结果在常量池中,且常量池中的内容不会有重复的
2、只要其中有一个是变量,结果就在对当中
3、如果拼接的结果调用了intern()方法,返回值在常量池中
s4在加上final后变成一个常量,根据总结的第一条,常量之间的拼接是发生在常量池的
易错题2
值传递机制:基本数据类型传的是具体值,引用数据类型传的是地址值。然后change方法中的引用数据类型又是String类型,相当于在change方法中,将类中的String str的地址值传递过来。因为String的不可变性,内容改变后的str指向了一个新的地址值,但是并没有改变原有的str,所以str没变。而char型数组ch不是引用类型,将其中一个元素进行改变,相当于基本数据类型的具体指的修改,会变
String常用方法
1、int length:返回字符串长度
2、char charAt(int index):返回index处的字符
3、boolean isEmpty():判断字符串是否为空
4、String toLowerCase():将String中所有字符转换为小写
String toUpperCase():将String中所有字符转换为大写
【注意】下面的s1并没有被修改
5、String trim():返回字符串的副本,忽略开头和结尾的若干空格
6、boolean equals(Object obj):比较字符串内容是否相同(严格区分大小写)
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
7、String concat(String str):将指定字符串连接到此字符串结尾,等价于“+”
8、int compareTo(String anotherString):比较两个字符串大小(结果是负的,当前调用方法的字符串小,正数大,零相等;涉及到字符串排序)
9、String substring(int beginIndex):返回一个新的字符串,他是从此字符串的beginIndex开始截取
String substring(int beginIndex, int endIndex):返回一个新的字符串,他是从此字符串的beginIndex开始,截取到endIndex(不包含)的一个子字符串。(左闭右开)
10、boolean endsWith(String suffix):测试此字符串是否已制定后缀结束
boolean startsWith(String prefix):测试此字符串是否已制定前缀开始
boolean startsWith(String prefix, int toffset):测试此字符串从指定位置开始的子字符串是否已制定前缀开始
11、boolean contains(CharSequence s):当且仅当此字符串中包含指定的char值序列时,返回true
12、int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex):从指定索引开始,返回指定字符串在此字符串中第一次出现处的索引
13、int lastIndexOf(String str):返回子字符串第一次出现出的索引(从末尾开始找)
int lastIndexOf(String str, int fromIndex):返回指定字符串在此字符串中最后一次出现出的索引,从指定索引开始反向搜索(说白了就是从末尾开始搜索)
什么情况下indexOf(String str)和lastIndexOf(String str)返回值相同?
str只有一个或没有时
14、String replace(char oldChar, char newChar):返回一个新的字符串,其中用newChar代替原来的oldChar
String replace(charSequence target, charSequence replacement):返回一个新的字符串,其中用新的字符串replacement代替原来的字符串target
15、String replaceAll(String regex, charSequence replacement):使用给定的字符串replacement替换此字符串匹配给定的正则表达式的子字符串(暂时先了解)
16、String replaceFirst(String regex, charSequence replacement):使用给定的字符串replacement替换此字符串匹配给定的正则表达式的第一个子字符串(暂时先了解)
17、boolean matches(String regex):告知此字符串是否匹配给定的正则表达式
18、String[ ] split(String regex):根据给定正则表达式的匹配拆分此字符串
String[ ] split(String regex, int limit):根据给定正则表达式的匹配拆分此字符串,最多不超多limit个,如果超过了剩下的全部放到最后一个元素中
String与char[ ]之间的转换
String——>char[ ]:调用String的toCharArray方法
char[ ]——>String:调用String的构造器
String与byte[ ]之间的转换
String——>char[ ]:调用String的getbytes方法(使用默认的字符集进行转换)
sysout中的语句是遍历数组
还可以指定编码集
byte[ ]——>String:调用String的构造器
字符集要一致!!!
二、StringBuffer类、StringBuilder类
String、StringBuffer、StringBuilder的异同
String:不可变的字符序列;底层使用char[ ]存储
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[ ]存储
StringBuilder:可变的字符序列;jdk5.0新增,线程不安全,效率高;底层使用char[ ]存储
源码分析:
String str=new String();//char[ ] value=new char[0];
String str1=new String(“abc”);//char[ ] value=new char[ ]{‘a’,‘b’,‘c’};
StringBuffer str2=new StringBuffer();//char[ ] value=new char[16],底层创建了一个长度为16的数组
问题1:StringBuffer数组长度
但是这里求的length实际上是返回数组中的元素个数,所以返回值是0不是16
问题2:扩容
在StringBuffer中如果数据盛不下了,需要扩容底层数组
默认情况下,扩容为原来的2倍+2,并将原有数组中内容复制到扩容后的数组中。
【建议】:尽量使用StringBuffer(int capacity)//指定底层数组容量的构造器;或StringBuilder(int capacity)
StringBuffer类常用方法(StringBuilder同样适用)
1、StringBuffer append(xxx):提供了很多append方法,用于字符串的拼接
2、StringBuffer delete(int start, int end):删除指定位置的内容(左闭右开)
3、StringBuffer replace(int start, int end, String str):把[start, end)位置替换为str
4、StringBuffer insert(int offset, xxx):提供了很多append方法,用于字符串的插入
5、StringBuffer reverse():将当前字符序列反转
6、public int indexOf(String str)
7、public String subString(int start, int end)
8、public int length()
9、public char charAt(int n)
10、public void setCharAt(int n, char ch)
总结:
增:append
删:delete
改:setCharAt、replace
查:charAt
插:insert
遍历:for+charAt
String、StringBuffer、StringBuilder的效率从高到低排列
StringBuilder > StringBuffer > String