总结1-String、StringBuffer、StringBuilder
对于这3个类,使用最多的应该是String类了,他们之间有区别,有联系。
首先,从最简单的地方开始说,他们都在同一个包下,java.lang.
这个包下。
一,首先说String
首先,字符串底层是通过char数组实现的。
1,String的两种实例化方式、两种实例化方式的区别
1)直接赋值;
2)通过关键字new;
String str1="hello";
String str2=new String("hello");
使用哪一种实例化字符串更合适呢?
参考:字符串的特点
其实,直接赋值更合适,因为一个字符串就是String的一个匿名对象。通过关键字new来创建,会产生一个毫无用处的垃圾对象,这个对象毫无用处但是还是被创建出来了,从他创建之后就开始等着gc回收了,浪费内存。
public class StringDemo{
public static void main(String args[]){
String str1 = new String("hello") ;
}
};
内存分析:
2,String的特点—>内容一旦声明则不可改变
public class StringDemo{
public static void main(String args[]){
String str = "hello" ; // 声明字符串
str = str + " world!!!" ; // 修改字符串
System.out.println("str = " + str) ;
}
};
内存分析:
实际上字符串内容的改变,改变的是内存地址的引用关系,所以,尽量避免这样的操作。
注:
实际上,对于这种直接赋值,然后通过加号,尾部追加改变字符串内容的方式,对于jvm来说操作还是相当快的,因为这两个内容都是在常量池中,但是,如果字符串的内容需要通过一系列运算才能得到的话,通过局部变量追加,jvm就老老实实的进行持续的应用的连接,断开,操作效率就很差了。
比如String str = "hello" ; str = str + " world!!!" ;
jvm会直接认为str=“hello world”
;
String、StringBuilder、StringBuffer的比较总结。
- String
首先,从性质上来说。String是字符串常量,改变内容是通过不断的产生新的对象,将现有对象的指向断开,指向新对象的方式实现的,也就是说String来实现字符串内容的改变,是不断的产生新对象和垃圾对象的过程,消耗内存,性能并不高。
其次,从继承结构上来说。String是实现了CharSequence接口。
- StringBuilder、StringBuffer
首先,还是从性质上说,StringBuilder和StringBuffer是字符串变量,操作的都是字符串缓冲区。通过在尾部追加来改变字符串内容,并不会产生新的对象。
其次,从继承结构上来说,StringBuilder和StringBuffer都继承了AbstractStringBuilder抽象类,这个AbstractStringBuilder抽象类是实现了CharSequence接口和Appendable接口的,所以StringBuilder和StringBuffer的的操作方法基本是一样的。
但是不同之处在于,StringBuilder的方法是没有通过synchronized关键字修饰的,所以速度很快,性能很高,但是也存在弱点:单线程的操作,无法保证线程操作的安全,在异步操作的时候,就会出错。而StringBuffer的方法都有这个锁修饰,所以性能上相对就降低了一些,但是由于这个锁的存在,保证了线程安全性。
所以:频繁改变字符串内容的操作中,不要使用String、单线程使用场景中可以使用StringBuilder、多线程改变字符串内容的情况下就需要使用StringBuffer。
分析—->三种方式改变字符串内容的性能比较
- 对于demo1这样的代码,其实jvm,是通过将String转换为StrinBuilder来操作的,操作速度还是相当快的。
对于demo2中的代码,jvm就会老老实实的去不断的断开原来的对象引用指向,创建新对象,并指向新的对象,之前的对象的内容就称为了垃圾等待gc回收。
demo1:
String string="this"+"is"+"a"+"test";
demo2:
String S1="this";
String S2="is";
String S3="a";
String S4="test";
String str=S1+S2+S3+S4;
- StringBuilder
是在jdk1.5之后引入的,是线程不安全的,单线程下操作字符串缓冲区,效率很高。
StringBuilder builder=new StringBuilder("this").append("is").append("a").append("test");
- StringBuffer
在jdk1.0就有了,由于有锁的存在,所以可以可以保证线程安全性,但是操作字符串缓冲区的速度就相对降低了一些。
StringBuffer buffer=new StringBuffer("this").append("is").append("a").append("test");
3,String的比较–两种比较方式(==,equals())
字符串的比较操作,“==”比较地址值,equals()比较内容
4,String类中的常用方法。
- 构造方法:
①可以将byte数组,byte数组中指定范围(位置)的内容转换为字符串,
转换中可以指定charset解码;
②可以将char数组,char数组指定范围(位置)的元素转换为字符串 。
③可以将int数组指定范围(位置)的元素转换为字符串。
④构造方法中也可以传入一个字符串。
⑤构造方法中可以传入一个StringBuilder或者StringBuffer将其转换为String。 public char charAt(int index)
返回字符串指定位置处的索引值。①
public int compareTo(String anotherString)
按字典顺序比较两个字符串。
②public int compareToIgnoreCase(String str)
按字典顺序比较两个字符串,不考虑大小写public String concat(String str)
将指定字符串连接到此字符串的结尾。public boolean contains(CharSequence s)
当且仅当此字符串包含指定的 char 值序列时,返回 true。- ①
public boolean equals(Object anObject)
将此字符串与指定的对象比较。
②public boolean equalsIgnoreCase(String anotherString)
将此 String 与另一个 String 比较,不考虑大小写。
③public boolean contentEquals(CharSequence cs)
将此字符串与指定的 CharSequence 比较。
④public boolean equalsIgnoreCase(String anotherString)
将此字符串与指定的 StringBuffer 比较。
7.① public boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束。
8. ①public boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始。
②public boolean startsWith(String prefix, int toffset)
测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
9. ①public static String format(Locale l, String format,Object... args)
使用指定的语言环境、格式字符串和参数返回一个格式化字符串
②public static String format(String format,Object... args)
使用指定的格式字符串和参数返回一个格式化字符串。始终使用 Locale.getDefault() 返回的语言环境。
10. 转换为byte数组
①public byte[] getBytes()
②public byte[] getBytes(Charset charset)
③public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
11. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组。
12. ①public int indexOf(int ch)
②public int indexOf(int ch, int fromIndex)
13. public boolean matches(String regex)
告知此字符串是否匹配给定的 正则表达式。
14. public String replace(char oldChar,
char newChar)
15. public String replaceAll(String regex,
String replacement)
16. public String[] split(String regex)
17. ①public String substring(int beginIndex, int endIndex)
②public String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的一个子字符串。
18. public char[] toCharArray()
转换为字符串
19. public String trim()
返回字符串的副本,忽略前导空白和尾部空白。
20. public static String valueOf(boolean b)
可以传入boolean类型、char类型、int类型、long类型、double类型将其转换为字符串。
StringBuffer和StringBuilder的操作方法就比较简单了。
- 追加,有很多重载,可以追加很多类型的数据。
public StringBuilder append(boolean b)
- 返回当前容量
public int capacity()
- 返回第一次出现的指定子字符串在该字符串中的索引
public int indexOf(String str)
4.将 boolean 参数的字符串表示形式插入此序列中
public StringBuilder insert(int offset,
boolean b)
- 使用给定 String 中的字符替换此序列的子字符串中的字符。
public StringBuilder replace(int start,
int end, String str)
- 将此字符序列用其反转形式取代。
public StringBuilder reverse()
- 返回一个新的 String,它包含此字符序列当前所包含字符的子序列。
public String substring(int start)