您的位置:首页 > 编程语言 > Java开发

Java源代码阅读——字符串相关

2017-03-08 13:02 393 查看
一 String类

字符串存贮在一个final数组value中,并且未对外提供修改其内元素的方法,所以String类是不可变的。

private final char value[];

1.1 构造方法

public String() {
this.value = "".value;
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
通过上述构造方法可知,字符串的构造是通过将一个数组赋给当前String的value数组完成的。

public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}


由上述可知,用StringBuffer构造字符串是线程安全的,而StringBuilder是线程不安全的,通常应该优先使用StringBuilder类,因为它支持所有与StringBuffer相同的操作,但由于它不执行同步,所以速度更快。

1.2 length()和empty()

public int length() {
return value.length;
}
public boolean isEmpty() {
return value.length == 0;
}
length通过返回数组的长度取得。
1.3 charAt()

public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}返回该索引对饮的数组值。

1.5 indexOf()

public int indexOf(int ch, int fromIndex) {
final int max = value.length;
if (fromIndex < 0) {
fromIndex = 0;
} else if (fromIndex >= max) {
// Note: fromIndex might be near -1>>>1.
return -1;
}

if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
final char[] value = this.value;
for (int i = fromIndex; i < max; i++) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return indexOfSupplementary(ch, fromIndex);
}
}通过返回ch在value中的所有取得。

1.6 subString()

public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}若beginIndex==0则直接返回当前String,否则new一个新String。

1.7 replace()

public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */

while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}如果确实发生了字符替换,将会new 一个新的String返回。toUpperCase()等若发生改变也返回的是新的String。

1.8 intern

public native String intern();

如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 

二 StringBuffer类

2.1 构造函数

public StringBuffer() {
super(16);
}其父类构造函数为:
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}即默认构造了大小为16的数组

public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
构造一个比当前字符串长16的字符串。

2.2 append()

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;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}


每次扩容为原数组长度的2倍+2,若不够则取count+len,即每次扩容胡至少为minimumCapacity=count+len。

三 StringBuilder类

3.1 构造函数

public StringBuilder() {
super(16);
}

类似StringBuffer。

四 StringBuffer VS StringBuilder

StringBuffer类的成员方法前面多了一个关键字:synchronized,所以它是线程安全的,由此带来的问题是效率低。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息