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 stringString greeting = "Hello";
那么这三者的区别是什么?
1、可变性查看源码简单来说,String类中使用final关键字修饰的字符数组保存字符串,所以String对象是不可变的:
String.java
public final class String implements java.io.Serializable, Comparable<String>, 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多线程,字符串缓冲区下操作大量数据 StringBuffer5、常用APIjava.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,反之返回falseboolean equals(Object other)//如果字符串与other相等(忽略大小写),返回true,反之返回falseboolean equalsIgnoreCase(String other) //如果字符串以prefix开头,返回trueboolean startsWith(String prefix) //如果字符串以suffix结尾,返回trueboolean endsWith(String suffix)//返回字符串str或代码点cp匹配的第一个子串开始的位置。这个位置从索引0或者fromIndex开始计算。//如果在原始串中不存在str,返回-1int 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()//追加一个字符串并返回thisStringBuilder append(char c)//将第i个代码单元设置为cvoid setCharAt(int i, chanr c)//在offset位置插入一个字符串并返回thisStringBuilder insert(int offset, String str)//删除偏移量从startIndex到endIndex-1的代码单元并返回thisStringBuilder delete(int startIdnex, int endIndex)//返回一个与构建器或缓冲器内容相同的字符串String toString()
java.lang.StringBuffer
与StringBuilder基本相同
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。