目錄
- 1. 不可變String
- 2.String、StringBuffer和StringBuilder
- 2.1 String常用api:
- 2.2 StringBuilder 和 StringBuffer
- 2.2.1StringBuilder
- 2.2.2 StringBuffer
- 2.2.3 總結
1. 不可變String
String物件都是不可變的:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
很顯然,String的值在內部是使用char陣列來保存,并且是final型別,這就意味著在初始化的時候被賦值將不會更改,String類中每一個看起來會修改String值得方法,實際上都是創建了一個新的String物件罷了,
2.String、StringBuffer和StringBuilder
2.1 String常用api:
- length() : 回傳String中字符個數,
- charAt() :回傳i索引上的char
- equals() : 判斷兩個字串是否相等:如果參考地址相同則直接回傳true,否則,如果是字串型別則將其轉化為char陣列逐一比對,
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- compareTo() : 按照詞典順序比較String內容,回傳呼叫者(this)與引數的第一個不相同字符的ascii碼差值 ,如果在相同回傳長度差值,
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
- contains() : 呼叫者(this)是否包含引數內容,jdk中呼叫indexOf方法
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
- indexOf() : 回傳此引數在該字串中的索引,不存在則回傳-1.
傳入的引數可以是char,char和起始查詢位置,或者是String,String和起始查詢位置,查詢方法是第一個指標先查找第一個匹配字符的起始位置然后第二個指標向后查找出整個字串,不匹配則i++繼續查找
public int indexOf(String str) {
return indexOf(str, 0);
}
public int indexOf(String str, int fromIndex) {
return indexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
/**
* Code shared by String and StringBuffer to do searches. The
* source is the character array being searched, and the target
* is the string being searched for.
*
* @param source the characters being searched.
* @param sourceOffset offset of the source string.
* @param sourceCount count of the source string.
* @param target the characters being searched for.
* @param targetOffset offset of the target string.
* @param targetCount count of the target string.
* @param fromIndex the index to begin searching from.
*/
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
- substring() : 可以注意的是string是小寫,用于截取字串,傳入的引數可以是起始位置,或者是起始位置和終止位置,實際上就是通過String的建構式重新生成一個字串,
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
- trim() : 洗掉兩端空白字符,
- valueOf() : 轉換成為字串,回傳的是原始值,和toString()的差別是toString()更強調的是對物件的反映,
2.2 StringBuilder 和 StringBuffer
2.2.1StringBuilder
StringBuilder 是可變字串,是執行緒不安全,但是也是執行速度更快的,默認初始容量為16,當然你也可以在建構式中傳入初始容量,初始的字串等,
public StringBuilder() {super(16);}
public StringBuilder(int capacity) {super(capacity);}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
空間不足時擴容則是原容量向左移動一位再加2相當于 原容量乘二再加二,
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;
}
- StringBuilder常用的方法有:append()追加字串,和reverse()翻轉字串等,
2.2.2 StringBuffer
StringBuffer也是可變字串,是執行緒安全的,但是執行速度不如StringBuilder,
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
大多數方法加了 synchronized 修飾,保證了執行緒安全,從而減低了執行速度,
2.2.3 總結
- 如果要操作少量的資料,用String ;單執行緒操作大量資料,用StringBuilder ;多執行緒操作大量資料,用StringBuffer,
- 相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多執行緒不安全的風險,所以確保你的模塊不會運行在多執行緒模式下,才可以采用 StringBuilder;否則還是用 StringBuffer,
- 為了獲得更好的性能,在構造 StringBuffer 或 StringBuilder 時應盡可能指定它們的容量,如果確定長度不超過16,則可以忽略,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/253473.html
標籤:java
上一篇:使用中綴運算式實作一個簡易計算機
下一篇:【高級開發進階】6.4 CAS
