String、StringBuffer、StringBuilder
字符串在开发中经常使用到,但是Java中提供三种字符串操作的类,String、StringBuffer以及StringBuilder,那么它们有什么区别以及怎么使用呢?
从概念上讲,Java字符串就是Unicode字符序列,例如,串"Java\u2122"由5个Unicode字符J、a、v、a和TM 。Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,很自然的叫做String。每个双引号“”括起来的字符串都是String类的一个实例:
创新互联建站专注于成都网站制作、成都网站建设、网页设计、网站制作、网站开发。公司秉持“客户至上,用心服务”的宗旨,从客户的利益和观点出发,让客户在网络营销中找到自己的驻足之地。尊重和关怀每一位客户,用严谨的态度对待客户,用专业的服务创造价值,成为客户值得信赖的朋友,为客户解除后顾之忧。
String e = ""; //an empty string
String greeting = "Hello";
那么这三者的区别是什么?
1、可变性
查看源码简单来说,String类中使用final关键字修饰的字符数组保存字符串,所以String对象是不可变的:
String.java
public final class String implements java.io.Serializable, Comparable, CharSequence {
private final char value[];
private int hash;
...
}
而StringBuilder和StringBuffer都继承自AbstractStringBuilder,在AbstractStringBuilder类中也是使用字符数组来保存字符串的,但是没有用final关键字修饰:
AbstractStringBuilder.java
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
AbstractStringBuilder(){
}
AbstractStringBuilder(int capacity){
valeu = new char[capacity];
}
...
}
StringBuilder.java
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
public StringBuilder() {
super(16);
}
...
}
StringBuffer.java
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
private transient char[] toStringCache;
public StringBuffer() {
super(16);
}
...
}
从而也可以看出三个类也是用final修饰的,所以是不可继承的。
2、线程安全性
String中的对象是不可变的,也可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder和StringBuffer的父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。而StringBuilder并没有对方法加同步锁,所以是线程不安全的。
3、性能
每次对String进行改变的时候,都会生成一个新的String对象,然后将引用指向新的String对象。StringBuffer和StringBuilder每次都是对对象本身进行操作,而不生成新的对象也不改变引用的指向。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10%-15%左右的性能提升,却要冒线程不安全的风险。
4、使用建议
- 操作少量数据 String
- 单线程,字符串缓冲区下操作大量数据 StringBuilder
- 多线程,字符串缓冲区下操作大量数据 StringBuffer
5、常用API
- java.lang.String
//返回给定位置的代码单元。
char charAt(int index)
//按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符串在other之后,返回一个正数;如果两个字符串相等,返回0.
int compareTo(String other)
//用数组中offset开始的count个码点构成一个字符串
new String(int[] codePoints, int offset, int count)
//如果字符串与other相等,返回true,反之返回false
boolean equals(Object other)
//如果字符串与other相等(忽略大小写),返回true,反之返回false
boolean equalsIgnoreCase(String other)
//如果字符串以prefix开头,返回true
boolean startsWith(String prefix)
//如果字符串以suffix结尾,返回true
boolean endsWith(String suffix)
//返回字符串str或代码点cp匹配的第一个子串开始的位置。这个位置从索引0或者fromIndex开始计算。
//如果在原始串中不存在str,返回-1
int indexOf(String str)
int indexOf(String str, int fromIndex)
int indexOf(int cp)
int indexOf(int cp, int fromIndex)
//返回字符串str或代码点cp匹配的最后一个子串开始的位置。这个位置从原始串结尾端或fromIndex开始计算
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)
int lastIndexOf(int cp)
int lastIndexOf(int cp, int fromIndex)
//返回字符串的长度
int length()
//返回一个新字符串。这个字符串用newString代替原始字符串中所有oldString。
//可以用String或StringBuffer或StringBuilder对象作为CharSequence参数。
String replace(CharSequence oldString, CharSequence newString)
//返回一个新字符串。这个字符串包含原始字符串中从beginIndex到串尾的所有代码单元
String substring(int beginIndex)
//返回一个新字符串。这个字符串包含原始字符串中从beginIndex到endindex-1的所有代码单元
String substring(int beginIndex, int endIndex)
//返回一个新字符串。这个字符串将原始字符串中的大写改为小写
String toLowerCase()
//返回一个新字符串。这个字符串将原始字符串中的小写改为大写
String toUpperCase()
//返回一个新字符串。这个字符串将删除原始字符串头部和尾部的空格
String trim()
//返回一个新字符串。用给定的定界符连接所有元素
String join(CharSequence delimiter, CharSequence... elements)
- java.lang.StringBulider
//构造一个空字符串构建器
StringBuilder()
//返回构建器或缓冲器中的代码单元数量
int length()
//追加一个字符串并返回this
StringBuilder append(char c)
//将第i个代码单元设置为c
void setCharAt(int i, chanr c)
//在offset位置插入一个字符串并返回this
StringBuilder insert(int offset, String str)
//删除偏移量从startIndex到endIndex-1的代码单元并返回this
StringBuilder delete(int startIdnex, int endIndex)
//返回一个与构建器或缓冲器内容相同的字符串
String toString()
- java.lang.StringBuffer
与StringBuilder基本相同
本文名称:String、StringBuffer、StringBuilder
本文链接:http://ybzwz.com/article/gppdjj.html