Java源代码阅读——字符串相关
2017-03-08 13:02
393 查看
一 String类
字符串存贮在一个final数组value中,并且未对外提供修改其内元素的方法,所以String类是不可变的。
private final char value[];
1.1 构造方法
public String() {
this.value = "".value;
}
由上述可知,用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的数组。
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;
}
每次扩容为原数组长度的2倍+2,若不够则取count+len,即每次扩容胡至少为minimumCapacity=count+len。
三 StringBuilder类
3.1 构造函数
public StringBuilder() {
super(16);
}
类似StringBuffer。
四 StringBuffer VS StringBuilder
StringBuffer类的成员方法前面多了一个关键字:synchronized,所以它是线程安全的,由此带来的问题是效率低。
字符串存贮在一个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,所以它是线程安全的,由此带来的问题是效率低。
相关文章推荐
- 如何阅读java项目的源代码
- 跟我一起阅读Java源代码之HashMap(三)
- 一个从源代码里提取中文字符串的java类
- hadoop编译源代码报错:package-info.java: 未结束的字符串字面值
- Java反转字符串和相关字符编码的问题解决
- JAVA基础复习:字符串相关
- java中字符串String相关的常用函数
- Java 推荐读物与源代码阅读
- java 源代码阅读转载
- 关于阅读源代码的总结(java)
- Java中的字符串相关解读
- 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接
- Java 推荐读物与源代码阅读
- 如何在Eclipse下查看JDK源代码以及java源代码阅读方法
- 跟我一起阅读Java源代码之HashMap(一)
- Java 推荐读物与源代码阅读
- Java初学_字符串相关
- Java 推荐读物与源代码阅读
- 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接
- 如何在Eclipse下查看JDK源代码以及java源代码阅读方法