Java 字符串之String,StringBuffer,StringBuilder

一:比拟
执行速度:StingBuilder>StringBuffer>String
String 字符串常量
StringBuffer 字符串变量(线程平安)
StringBuilder 字符串变量(线程不平安),都实现了CharSequence接口示意有序的字符汇合

CharSequence接口有几个办法:
1.获取指定索引的字符:public char charAt(int index)
2.获取字符串长度:public int length()
3.截取局部字符串:public CharSequence subSequence(int start, int end)
4.转成String类型:public String toString()
二:String字符串类型
Java String类为什么是final的?
1.为了实现字符串池,2.为了线程平安,3.为了实现String能够创立HashCode不可变性
final 润饰类不能被继承,即它不能领有本人的子类
final 润饰办法不能被重写
final 润饰的变量,无论是类属性,对象属性,形参,还是局部变量,都须要进行初始化操作。
String类不可变性的益处
1.只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现能够在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。
如果字符串是可变的,那么会引起很重大的平安问题。因为字符串是不可变的,所以它的值是不可扭转的,否则扭转字符串指向的对象的值,造成安全漏洞。
2.因为字符串是不可变的,所以是多线程平安的,同一个字符串实例能够被多个线程共享。这样便不必因为线程平安问题而应用同步。字符串本人便是线程平安的。
类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的毁坏。
3.因为字符串是不可变的,所以在它创立的时候hashcode就被缓存了,不须要从新计算。这就使得字符串很适宜作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都应用字符串。

public final class String implements Serializable, Comparable<String>, CharSequence{}

String 的函数表

//构造函数无参public String() public String(String original)//char数组类型转成Stringpublic String(char[] value) //char数组类型,起始地位,和总数public String(char[] value, int offset, int count) //字节数组类型public String(byte[] bytes) //字节数组类型,起始地位,长度public String(byte[] bytes, int offset, int length) //字节数组类型,对应编码public String(byte[] bytes, String charsetName)例子:String aa=new String(new byte[]{(byte)0x5b,(byte)0x57},"utf-8");//字节数组类型,起始地位,长度,对应编码public String(byte[] bytes, int offset, int length, String charsetName) //字节数组类型,字符对应编码public String(byte[] bytes, Charset charset)例子:String aa=new String(new byte[]{(byte)0x5b,(byte)0x57},Charset.forName("gbk"));//字节数组类型,起始地位,长度,字符对应编码public String(byte[] bytes, int offset, int length, Charset charset) public String(int[] codePoints, int offset, int count) //StringBuffer和StringBuilder转成Stringpublic String(StringBuffer buffer) public String(StringBuilder builder) //依据索引获取字符public char charAt(int index) public int codePointAt(int index) public int codePointBefore(int index) public int codePointCount(int beginIndex, int endIndex)//比拟2个String的大小public int compareTo(String anotherString) //比拟2个String的大小(疏忽大小写)public int compareToIgnoreCase(String str)//字符串前面追加字符串public String concat(String str) //和StringBuffer的内容比拟public boolean contentEquals(StringBuffer sb) public boolean contentEquals(CharSequence cs) public static String copyValueOf(char[] data, int offset, int count)public static String copyValueOf(char[] data) //比拟2个String是否相等public boolean equals(Object anObject) //比拟2个String是否相等(疏忽大小写)public boolean equalsIgnoreCase(String anotherString) public static String format(String format, Object[] args) public static String format(Locale l, String format, Object[] args) public int hashCode() //依据字符查问索引public int indexOf(int ch) //依据字符,字符地位查问索引public int indexOf(int ch, int fromIndex) //依据字符串查问索引public int indexOf(String str) //依据字符串,字符地位查问索引public int indexOf(String str, int fromIndex) public String intern() //依据字符从后往前查问索引public int lastIndexOf(int ch) public int lastIndexOf(int ch, int fromIndex) //依据字符串从后往前查问索引public int lastIndexOf(String str) public int lastIndexOf(String str, int fromIndex) //字符串长度public int length() //匹配字符串public boolean matches(String regex) public int offsetByCodePoints(int index, int codePointOffset) //2个字符串比拟开始地位,字符串,完结地位,长度public boolean regionMatches(int toffset, String other, int ooffset, int len) //2个字符串比拟疏忽大小写,开始地位,字符串,完结地位,长度public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) //替换字符public String replace(char oldChar, char newChar) public String replace(CharSequence target, CharSequence replacement)//全副替换public String replaceAll(String regex, String replacement) //替换第一次呈现的字符public String replaceFirst(String regex, String replacement) //宰割字符成字符串数组public String[] split(String regex, int limit) public String[] split(String regex) //判断结尾字符是不是输出字符,索引地位开始public boolean startsWith(String prefix, int toffset) /判断结尾字符是不是输出字符public boolean startsWith(String prefix) //判断结尾字符串是不是输出字符public boolean endsWith(String suffix)//判断字符串是不是蕴含**public boolean contains(CharSequence s) public CharSequence subSequence(int beginIndex, int endIndex) //截取字符串局部public String substring(int beginIndex) public String substring(int beginIndex, int endIndex) //转成字符数组public char[] toCharArray() //转成小写public String  toLowerCase(Locale locale)public String  toLowerCase()//转成Stringpublic String toString()//转成大写public String toUpperCase(Locale locale)public String toUpperCase() public String trim()//把各种对象转成Stringpublic static String valueOf(Object obj) public static String valueOf(char[] data) public static String valueOf(char[] data, int offset, int count)public static String valueOf(boolean b) public static String valueOf(char c) public static String valueOf(int i)public static String valueOf(long l)public static String valueOf(float f) public static String valueOf(double d) //获取对应的字符串的字节数组public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)public byte[] getBytes(String charsetName) public byte[] getBytes(Charset charset) public byte[] getBytes() public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) public boolean isEmpty()

三:StringBuffer可变字符串变量
StringBuffer对象初始化,通常状况下应用构造函数进行初始化。
StringBuffer的构造函数

无参结构默认调用容量16的有参结构public StringBuffer(){super(16)}有参结构,容量多少public StringBuffer(int capacity) {    super(capacity);}传入字符串结构,容量是字符串长度+16public StringBuffer(String str)

相干办法

将制订字符追加到字符序列1.public StringBuffer append(String s)//字符数组增加指定地位字符序列2.public StringBuffer append(char[] str, int offset, int len) //将此字符序列用其反转模式取代3.public StringBuffer reverse()//将int参数的字符串示意模式插入此序列中4.public insert(int offset, int i)//移除此序列的子字符串中的字符5.public delete(int start, int end)//应用给定String中的字符替换此序列的子字符串中的字符。6.replace(int start, int end, String str)//返回以后容量7.int capacity()返回此序列中指定索引处的char值8.char charAt(int index)//确保容量至多等于指定的最小值9.void ensureCapacity(int minimumCapacity)//将字符从此序列复制到指标字符数组 dst10.void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)//返回第一次呈现的指定子字符串在该字符串中的索引11.int indexOf(String str)//返回最左边呈现的指定子字符串在此字符串中的索引12.int lastIndexOf(String str)//将给定索引处的字符设置为 ch13.void setCharAt(int index, char ch)//设置字符序列的长度14.void setLength(int newLength)//返回一个新的字符序列,该字符序列是此序列的子序列15.CharSequence subSequence(int start, int end)//返回一个新的String,它蕴含此序列以后所蕴含的字符子序列16.String substring(int start, int end)

StringBuffer,StringBuilder扩容形式
构造函数中调用append办法

public StringBuffer(String str) {    super(str.length() + 16); append(str);}

append办法中调用AbstractStringBuilder父类的append办法

public synchronized StringBuffer append(String str) { super.append(str); }

父类中append办法

public AbstractStringBuilder append(String str) {    if (str == null)//先判断字符串是否为空        return appendNull(); int len = str.length();//字符串长度 ensureCapacityInternal(count + len);//此办法判断字符数组value的容量是否足够,cout是字符被应用的容量+传进去的字符长度 str.getChars(0, len, value, count); count += len; return this;}

跟进去ensureCapacityInternal看看

private void ensureCapacityInternal(int minimumCapacity) {    // overflow-conscious code if (minimumCapacity - value.length > 0) {//value默认的长度是16+传入的字符长度        value = Arrays.copyOf(value, newCapacity(minimumCapacity)); }}

a.如果传进来的参数小于value数组的长度,那么阐明容量曾经足够,不须要扩容
b.如果传进来的参数大于value数组的长度,阐明本来设定的容量曾经不够用,须要扩容解决,这里的Arrays.copyOf(char[] a,int b),就是将a这个数组复制到一个b长度的新数组中,并返回这个b长度的数组,这里的b就是newCapacity(minimumCapacity)
如果数组空间不够传入,newCapactiy()

private int newCapacity(int minCapacity) {    // overflow-conscious code int newCapacity = (value.length << 1) + 2;//新的数组空间左移一位+2,相当于*2容量+2 if (newCapacity - minCapacity < 0) {        newCapacity = minCapacity;//相当赋给新的数组 }    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)//最大容量2147483647-8        ? hugeCapacity(minCapacity)        : newCapacity;}

四:StringBuffer和StringBuilder的区别
1.StringBuffer的继承关系和StringBuilder完全一致,因而StringBuffer外部也是调用的AbstractStringBuilder的办法,所以很多办法的了解都和StringBuilder相差无几

2.但和StringBuilder不同的是,StringBuffer的每个办法上都用了synchronized润饰,当波及到多线程调用时StringBuffer是线程平安的,与之绝对的StringBuilder便线程不平安了,但因而StringBuilder的效率要比StringBuffer高

3.所以,当咱们在多线程环境下该当应用StringBuffer以保障线程平安,而在单线程环境下应用StringBuilder以提高效率