真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

String、StringBuffer和StringBuilder的使用方法

前言

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、網(wǎng)絡(luò)空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、玉泉街道網(wǎng)站維護(hù)、網(wǎng)站推廣。

相信很多程序員在使用String、StringBuilder和StringBuffer的時(shí)候都知道怎么使用,卻并不會(huì)去看其原理,

在學(xué)習(xí)這三個(gè)類之前先認(rèn)識(shí)一下CharSequence接口和Appendable接口:

CharSequence接口,出自于JDK1.4,有如下幾個(gè)常用的方法:

int length(); 返回字符序列長(zhǎng)度

char charAt(int index); 返回字符序列在指定索引處的字符

CharSequence subSequence(int start, int end); 截取字符序列從索引start到end之間的值。包括start不包括end。例如:長(zhǎng)度為5的字符序列“12345”,截圖0到3的值為“123”,即真正的返回值為索引start到end-1之間的值。

Appendable接口,出自JDK1.5,有如下幾個(gè)常用方法:

Appendable append(CharSequence csq) throws IOException; 拼接字符序列

Appendable append(CharSequence csq, int start, int end) throws IOException; 拼接字符序列指定區(qū)間內(nèi)的字符序列,包括start不包括end。即真正拼接的值為索引start到end-1之間的值。

Appendable append(char c) throws IOException; 拼接字符

概括

String類是字符串常量,是不可更改的常量。而StringBuffer是字符串變量,它的對(duì)象是可以擴(kuò)充和修改的。

 StringBuffer類的構(gòu)造函數(shù)

 public StringBuffer()

 創(chuàng)建一個(gè)空的StringBuffer類的對(duì)象。

 public StringBuffer( int length )

 創(chuàng)建一個(gè)長(zhǎng)度為 參數(shù)length 的StringBuffer類的對(duì)象。

 注意:如果參數(shù)length小于0,將觸發(fā)NegativeArraySizeException異常。

 public StringBuffer( String str )

 用一個(gè)已存在的字符串常量來(lái)創(chuàng)建StringBuffer類的對(duì)象。

StringBuffer類

StringBuffer類,繼承AbstractStringBuilder,實(shí)現(xiàn)Serializable序列化,操作上是線程安全的,線程安全的原因就是該類進(jìn)行數(shù)據(jù)操作的相關(guān)方法都加了synchronized關(guān)鍵字,而StringBuilder則都沒(méi)有加。

toStringCache變量:使用transient修飾,不參與序列化,作為toString方法緩存用

默認(rèn)構(gòu)造器:調(diào)用父類構(gòu)造器,傳遞一個(gè)默認(rèn)的長(zhǎng)度值16,父類構(gòu)造器創(chuàng)建一個(gè)長(zhǎng)度為16的字符數(shù)組;

參數(shù)為int的構(gòu)造器:參數(shù)為int的構(gòu)造器意思是構(gòu)造一個(gè)指定長(zhǎng)度的字符數(shù)組

參數(shù)為String和CharSequence的構(gòu)造器:會(huì)構(gòu)造一個(gè)長(zhǎng)度為(16+CharSequence字符長(zhǎng)度)或者(16+String字符串長(zhǎng)度)的字符數(shù)組。然后再拼接一下參數(shù)中的字符或者字符串,如果參數(shù)為null會(huì)拋出空指針異常(NullPointerException)。

length方法:返回實(shí)際數(shù)據(jù)長(zhǎng)度

capacity方法:返回父類構(gòu)造器的字符數(shù)組長(zhǎng)度

public final class StringBuffer extends AbstractStringBuilder

implements java.io.Serializable, CharSequence{

private transient char[] toStringCache;

/** use serialVersionUID from JDK 1.0.2 for interoperability */

static final long serialVersionUID = 3388685877147921107L;

public StringBuffer() {

super(16);

}

public StringBuffer(int capacity) {

super(capacity);

}

public StringBuffer(String str) {

super(str.length() + 16);

append(str);

}

public StringBuffer(CharSequence seq) {

this(seq.length() + 16);

append(seq);

}

@Override

public synchronized int length() {

return count;

}

@Override

public synchronized int capacity() {

return value.length;

}

接下來(lái)看一看一些相關(guān)操作的方法:

可以看到如拼接,插入,刪除,替換之類的操作都是調(diào)用父類的方法,并且返回的是調(diào)用該方法的類對(duì)象,這就表明StringBuffer類在進(jìn)行數(shù)據(jù)改變的操作后返回類對(duì)象本身,原因就是父類中儲(chǔ)存數(shù)據(jù)的字符數(shù)組value沒(méi)有final所修飾,所以可以做到修改數(shù)據(jù)而不改變類對(duì)象。

而String類中儲(chǔ)存數(shù)據(jù)的字符數(shù)組變量value是被final修飾的,也就說(shuō)明無(wú)法對(duì)String類對(duì)象的值進(jìn)行直接的修改,所以對(duì)其進(jìn)行數(shù)據(jù)改變操作的返回值都是new String(XXX),也就是每個(gè)返回值都是一個(gè)新的String對(duì)象,所以String類不適合大量的數(shù)據(jù)值改變的操作。

toStringCache變量:只有在調(diào)用toString方法的時(shí)候給予賦值操作,臨時(shí)儲(chǔ)存數(shù)據(jù),然后轉(zhuǎn)換為Sting對(duì)象當(dāng)做返回值。而每次對(duì)數(shù)據(jù)進(jìn)行改變的時(shí)候都會(huì)重置變量值,保證每次toString之前該變量都是空。

@Override

public synchronized StringBuffer append(String str) {

toStringCache = null;

super.append(str);

return this;

}

@Override

public synchronized StringBuffer delete(int start, int end) {

toStringCache = null;

super.delete(start, end);

return this;

}

@Override

public synchronized StringBuffer replace(int start, int end, String str) {

toStringCache = null;

super.replace(start, end, str);

return this;

}

@Override

public synchronized StringBuffer insert(int index, char[] str, int offset,

int len)

{

toStringCache = null;

super.insert(index, str, offset, len);

return this;

}

@Override

public int indexOf(String str) {

// Note, synchronization achieved via invocations of other StringBuffer methods

return super.indexOf(str);

}

@Override

public synchronized int indexOf(String str, int fromIndex) {

return super.indexOf(str, fromIndex);

}

@Override

public int lastIndexOf(String str) {

// Note, synchronization achieved via invocations of other StringBuffer methods

return lastIndexOf(str, count);

}

@Override

public synchronized int lastIndexOf(String str, int fromIndex) {

return super.lastIndexOf(str, fromIndex);

}

@Override

public synchronized StringBuffer reverse() {

toStringCache = null;

super.reverse();

return this;

}

@Override

public synchronized String toString() {

if (toStringCache == null) {

toStringCache = Arrays.copyOfRange(value, 0, count);

}

return new String(toStringCache, true);

}

StringBuilder類

StringBuilder類和StringBuffer差不多,少了一個(gè)toStringCache變量,所以的操作方法都沒(méi)有添加sybchronized關(guān)鍵字,所以StringBuilder是線程不安全的類。就不多說(shuō)了哈(*^▽^*)。

AbstractStringBuilder

AbstractStringBuilder產(chǎn)于JDK1.5,實(shí)現(xiàn)Appendable接口和CharSequence接口

該類只能被繼承,有兩個(gè)子類StringBuffer和StringBuilder,會(huì)默認(rèn)調(diào)用有參構(gòu)造器,指定初始化的字符串?dāng)?shù)據(jù)長(zhǎng)度

value: 實(shí)例化時(shí)創(chuàng)建出來(lái)的字符數(shù)組

count: 實(shí)際數(shù)據(jù)包含的字符的長(zhǎng)度

length方法:返回實(shí)際數(shù)據(jù)包含的字符的長(zhǎng)度

capacity方法:返回字符數(shù)組的大小

代碼如下:

abstract class AbstractStringBuilder implements Appendable, CharSequence {

char[] value;

int count;

AbstractStringBuilder() {

}

AbstractStringBuilder(int capacity) {

value = new char[capacity];

}

@Override

public int length() {

return count;

}

public int capacity() {

return value.length;

}

數(shù)據(jù)儲(chǔ)存空間操作相關(guān)方法:

ensureCapacityInternal:每次進(jìn)行數(shù)據(jù)改變操作之前都會(huì)調(diào)用的方法,其意在于確保數(shù)組變量value有能力承受接下來(lái)的改變,說(shuō)白了就是對(duì)數(shù)據(jù)操作的之前改變字符數(shù)組大小,使其容量能足夠接下來(lái)的操作使用而不出現(xiàn)錯(cuò)誤。

MAX_ARRAY_SIZE:私有靜態(tài)常量,值為 Integer.MAX_VALUE - 8,按照文檔翻譯來(lái)說(shuō),就是字符數(shù)組的最大容量,但是卻沒(méi)有達(dá)到Integer的最大值,原因是某些JVM虛擬機(jī)會(huì)在一個(gè)數(shù)組中保留一些標(biāo)題詞,如果強(qiáng)行嘗試區(qū)分配超過(guò)這個(gè)容量的數(shù)組可能會(huì)導(dǎo)致拋出異常OutOfMemoryError:請(qǐng)求的數(shù)組大小超過(guò)VM限制。

newCapacity:重新設(shè)置字符數(shù)組的容量,并作為返回值。參數(shù)表示字符數(shù)組的最小容量,首先要知道字符串?dāng)?shù)組初始長(zhǎng)度為16,擴(kuò)容方式為原字符數(shù)組長(zhǎng)度左移一位后再加2(原字符數(shù)組長(zhǎng)度乘以2,再加2)。該方法就是比較一次擴(kuò)容后value長(zhǎng)度值newCapacity和參數(shù)指定的最小值minCapacity,如果一次擴(kuò)容滿足最小值需求,則使用newCapacity,如果不滿于則直接使用minCapacity并且賦值于newCapacity,最后判斷minCapacity的大小是否大于0并小于指定的MAX_ARRAY_SIZE的值,如果滿足則返回minCapacity的值,如果不滿足則表示要求的最小值超過(guò)了建議的最大值容量,那將把minCapacity傳遞給為hugeCapacity方法,并以該方法的返回值作為本方法的返回值,如下。鄭州專業(yè)婦科醫(yī)院 http://www.hnzzkd.com/

hugeCapacity:如果參數(shù)給定值超過(guò)Integer的類型最大值,拋出內(nèi)存溢出異常,如果小于Integer的最大值,則和AbstractStringBuilder類的建議值對(duì)比,哪一個(gè)值大,則使用哪一個(gè)值作為返回值。

trimToSize:去除多余的數(shù)組儲(chǔ)存空間,提高空間利用率。比較數(shù)組空間value的大小和實(shí)際數(shù)據(jù)count大小,如果實(shí)際數(shù)據(jù)元素小于value,則表示實(shí)際數(shù)據(jù)并未占滿分配的空間,調(diào)用Arrays.copyOf方法把value中的空間鋪滿,返回鋪滿后的value值,

setLength:設(shè)置當(dāng)前序列的長(zhǎng)度為指定的參數(shù)長(zhǎng)度newLength,如果當(dāng)前序列的長(zhǎng)度超出指定長(zhǎng)度newLength,就把已有序列的前面長(zhǎng)度為newLength的字符拷貝到新字符序列里,多出來(lái)的一部分舍棄。如果不超過(guò)newLegth,原有數(shù)據(jù)不變,就把缺少的幾個(gè)位置的數(shù)據(jù)設(shè)置為空字符。

private void ensureCapacityInternal(int minimumCapacity) {

// overflow-conscious code

if (minimumCapacity - value.length > 0) {

value = Arrays.copyOf(value,

newCapacity(minimumCapacity));

}

}

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private int newCapacity(int minCapacity) {

// overflow-conscious code

int newCapacity = (value.length << 1) + 2;

if (newCapacity - minCapacity < 0) {

newCapacity = minCapacity;

}

return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)

? hugeCapacity(minCapacity)

: newCapacity;

}

private int hugeCapacity(int minCapacity) {

if (Integer.MAX_VALUE - minCapacity < 0) { // overflow

throw new OutOfMemoryError();

}

return (minCapacity > MAX_ARRAY_SIZE)

? minCapacity : MAX_ARRAY_SIZE;

}

public void trimToSize() {

if (count < value.length) {

value = Arrays.copyOf(value, count);

}

}

public void setLength(int newLength) {

if (newLength < 0)

throw new StringIndexOutOfBoundsException(newLength);

ensureCapacityInternal(newLength);

if (count < newLength) {

Arrays.fill(value, count, newLength, '\0');

}

count = newLength;

}

接下來(lái)看一下實(shí)際的數(shù)據(jù)操作,這里以最常用的拼接和替換為例:

appendNull:先擴(kuò)容,然后依次拼接字符n u l l,拼接的同時(shí)進(jìn)行count++;

append:先判斷字符串是否為null,如果是執(zhí)行appendNull,如果不是空,則獲取目標(biāo)對(duì)象的長(zhǎng)度,然后進(jìn)行擴(kuò)容,然后把目標(biāo)對(duì)象拷貝到value的后面。然后更新數(shù)據(jù)的大小count。返回類對(duì)象

replace:先判斷一系列索引越界問(wèn)題,如果都沒(méi)問(wèn)題檢查end是否超出count,超出了則修改end的值為count,獲取目標(biāo)字符串的長(zhǎng)度,計(jì)算經(jīng)過(guò)替換后的數(shù)據(jù)長(zhǎng)度。原長(zhǎng)度減去要被替換的長(zhǎng)度加上要替換成的字符串長(zhǎng)度:count-(end-start)+len。計(jì)算完成后更新字符數(shù)組大小,拷貝字符后更新count的值。返回類對(duì)象

private AbstractStringBuilder appendNull() {

int c = count;

ensureCapacityInternal(c + 4);

final char[] value = this.value;

value[c++] = 'n';

value[c++] = 'u';

value[c++] = 'l';

value[c++] = 'l';

count = c;

return this;

}

public AbstractStringBuilder append(String str) {

if (str == null)

return appendNull();

int len = str.length();

ensureCapacityInternal(count + len);

str.getChars(0, len, value, count);

count += len;

return this;

}

public AbstractStringBuilder replace(int start, int end, String str) {

if (start < 0)

throw new StringIndexOutOfBoundsException(start);

if (start > count)

throw new StringIndexOutOfBoundsException("start > length()");

if (start > end)

throw new StringIndexOutOfBoundsException("start > end");

if (end > count)

end = count;

int len = str.length();

int newCount = count + len - (end - start);

ensureCapacityInternal(newCount);

System.arraycopy(value, end, value, start + len, count - end);

str.getChars(value, start);

count = newCount;

return this;

}

public AbstractStringBuilder delete(int start, int end) {

if (start < 0)

throw new StringIndexOutOfBoundsException(start);

if (end > count)

end = count;

if (start > end)

throw new StringIndexOutOfBoundsException();

int len = end - start;

if (len > 0) {

System.arraycopy(value, start+len, value, start, count-end);

count -= len;

}

return this;

}


本文名稱:String、StringBuffer和StringBuilder的使用方法
網(wǎng)頁(yè)路徑:http://weahome.cn/article/pjhjss.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部