JDK1.8源码阅读记录
JAVA.LANG包
String类
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
说明
final关键字修饰的类,说明该类不能被继承,是线程安全的。
String类实现了三个接口,Serializable接口用于序列化,Comparable接口用于字符串比较,CharSequence用于实现字符数组操作。
属性 value[]
private final char value[];
该属性被用来存储字符,final修饰,表示该值一旦确定就不可改变。
数组类型的值表示指向,因此虽然该数组指向的地址不可改变,但我们还是可以改变数组内容的。
属性 hash
private int hash;
用于缓存String的hash值。
属性 serialVersionUID、serialPersistentFields
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
static+final修饰,表示是类常量。serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
serialVersionUID与serialPersistentFields都是用于对象序列化。
构造函数
public String() {
this.value = "".value;
}
无参构造,初始化一个新创建的String对象,使其表示一个空字符序列。注意,由于字符串是不可变的,因此不需要使用此构造函数。
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
初始化一个新创建的String对象,以便它表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要original的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
分配一个新的String,以便它表示字符数组参数中当前包含的value.length个字符的序列。 字符数组的内容已复制;字符数组的后续修改不会影响此次创建的字符串。
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
以value[]数组为样本,选择性地创建String对象。offset参数表示想要从母数组开始复制的位置,count指定子数组的长度(或理解为想要复制字符的数目),该方法表示从母数组的offset位置开始,复制count个字符给新的数组。
public String(int[] codePoints, int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= codePoints.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > codePoints.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
final int end = offset + count;
// Pass 1: Compute precise size of char[]
int n = count;
for (int i = offset; i < end; i++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
continue;
else if (Character.isValidCodePoint(c))
n++;
else throw new IllegalArgumentException(Integer.toString(c));
}
// Pass 2: Allocate and fill in char[]
final char[] v = new char[n];
for (int i = offset, j = 0; i < end; i++, j++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
v[j] = (char)c;
else
Character.toSurrogates(c, v, j++);
}
this.value = v;
}
分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。offset和count参数与上个方法类似。
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count) {
checkBounds(ascii, offset, count);
char value[] = new char[count];
if (hibyte == 0) {
for (int i = count; i-- > 0;) {
value[i] = (char)(ascii[i + offset] & 0xff);
}
} else {
hibyte <<= 8;
for (int i = count; i-- > 0;) {
value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
}
}
this.value = value;
}
已过时。 该方法无法将字节正确地转换为字符。从 JDK 1.1 开始,完成该转换的首选方法是使用带有 Charset、字符集名称,或使用平台默认字符集的 String 构造方法。
@Deprecated
public String(byte ascii[], int hibyte) {
this(ascii, hibyte, 0, ascii.length);
}
已过时。 该方法无法将字节正确地转换为字符。从 JDK 1.1 开始,完成该转换的首选方法是使用带有 Charset、字符集名称,或使用平台默认字符集的String 构造方法。
private static void checkBounds(byte[] bytes, int offset, int length) {
if (length < 0)
throw new StringIndexOutOfBoundsException(length);
if (offset < 0)
throw new StringIndexOutOfBoundsException(offset);
if (offset > bytes.length - length)
throw new StringIndexOutOfBoundsException(offset + length);
}
检查界限,对给出的数组、offset、length进行运算比较,若跨界,则抛出异常。
public String(byte bytes[], int offset, int length, String charsetName)
throws UnsupportedEncodingException {
if (charsetName == null)
throw new NullPointerException("charsetName");
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(charsetName, bytes, offset, length);
}
charsetname指定字符集解码,根据解码出来的结果进行选择性构造String对象。
public String(byte bytes[], int offset, int length, Charset charset) {
if (charset == null)
throw new NullPointerException("charset");
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(charset, bytes, offset, length);
}
charset指定字符集解码,根据解码出来的结果进行选择性构造String对象。
public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException {
this(bytes, 0, bytes.length, charsetName);
}
charsetname指定字符集解码,根据解码出来的结果进行构造String对象。
public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
}
charset指定字符集解码,根据解码出来的结果进行构造String对象。
public String(byte bytes[], int offset, int length) {
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(bytes, offset, length);
}
通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
通过使用平台的默认字符集解码构造一个新的 String。
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
synchronized 是 Java 中的关键字,是利用锁的机制来实现同步的。
用synchronized 来给buffer加锁,保证了在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。
由于StringBuffer 是可变的,而String是不可变的,因此通过synchronized 来让StringBuffer对象暂时保持不变,以构造不变的String对象。
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
以StringBuilder 为参数,构造String对象。
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
该构造函数复制给定的char []。
常用函数
length()
public int length() {
return value.length;
}
返回此字符串的长度。
isEmpty()
public boolean isEmpty() {
return value.length == 0;
}
判断该字符串是否为空。
charAt(int index)
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
根据索引值,取出此字符串该位置的字符。
注:索引值从0开始,即第一个字符位置为0。
codePointAt(int index)
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
此方法返回字符索引处的代码点值。
codePointBefore(int index)
public int codePointBefore(int index) {
int i = index - 1;
if ((i < 0) || (i >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointBeforeImpl(value, index, 0);
}
此方法返回字符索引前一个位置处的代码点值。
codePointCount(int beginIndex, int endIndex)
public int codePointCount(int beginIndex, int endIndex) {
if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
throw new IndexOutOfBoundsException();
}
return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
}
这个方法返回指定的文本范围的Unicode代码点数。
getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
将字符串的srcBegin到(srcEnd-1)位置的char字符代替char数组dest,并且替换的位置在从destBegin开始。
getBytes(String charsetName)、getBytes(Charset charset)
public byte[] getBytes(String charsetName)
throws UnsupportedEncodingException {
if (charsetName == null) throw new NullPointerException();
return StringCoding.encode(charsetName, value, 0, value.length);
}
public byte[] getBytes(Charset charset) {
if (charset == null) throw new NullPointerException();
return StringCoding.encode(charset, value, 0, value.length);
}
用指定的字符集编码对字符串进行编码,返回字节数组。
getBytes()
public byte[] getBytes() {
return StringCoding.encode(value, 0, value.length);
}
对字符串进行默认编码,返回字节数组。
equals(Object anObject)
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;
}
重写equals方法,由于String是引用类型,可能会出现字符串内容相同但引用不相同的情况,因此我们一般比较的是字符串内容是否相等,故在上述方法中,我们先判断引用是否相同,若相同则字符串内容必相同。否则的话,我们再判断变量是否是字符串类型,不是的话则必不相同;是的话则再进一步判断两个字符串的长度以及各个位置上的字符是否一致,若都一致,则判定为两个对象相同。
contentEquals(StringBuffer sb)
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence)sb);
}
private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
char v1[] = value;
char v2[] = sb.getValue();
int n = v1.length;
if (n != sb.length()) {
return false;
}
for (int i = 0; i < n; i++) {
if (v1[i] != v2[i]) {
return false;
}
}
return true;
}
将此字符串与指定的StringBuffer比较。当且仅当此String表示与指定的StringBuffer相同的字符序列时,结果为true。
contentEquals(CharSequence cs)
public boolean contentEquals(CharSequence cs) {
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
if (cs instanceof StringBuffer) {
synchronized(cs) {
return nonSyncContentEquals((AbstractStringBuilder)cs);
}
} else {
return nonSyncContentEquals((AbstractStringBuilder)cs);
}
}
// Argument is a String
if (cs instanceof String) {
return equals(cs);
}
// Argument is a generic CharSequence
char v1[] = value;
int n = v1.length;
if (n != cs.length()) {
return false;
}
for (int i = 0; i < n; i++) {
if (v1[i] != cs.charAt(i)) {
return false;
}
}
return true;
}
将此字符串与指定的CharSequence比较。当且仅当此String表示与指定序列相同的char值序列时,结果为true。
equalsIgnoreCase(String anotherString)
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
忽略大小写,进行比较是否相等。
compareTo(String anotherString)
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;
}
按字典顺序比较两个字符串。 比较是基于字符串中每个字符的Unicode值。在字典上比较此String对象表示的字符序列与自变量字符串表示的字符序列。如果此String对象在字典上在参数字符串之前,则结果为负整数。如果此String对象在字典上紧随参数字符串,则结果为正整数。如果字符串相等,则结果为零。
compareTo恰好在 equals(Object)方法返回 true时返回 0。 这是字典顺序的定义。如果两个字符串不同,则它们要么在某个索引处具有不同的字符,要么它们的长度不同,或两者都有。如果它们在一个或多个索引位置上具有不同的字符,在这种情况下,compareTo返回两个字符串中位置 k的两个字符值的差,即值:this.charAt( k)-anotherString.charAt(k)。
如果在索引位置上没有区别,则较短的字符串在字典上在较长的字符串之前。在这种情况下,compareTo返回字符串的长度之差,即值:this.length()-anotherString.length()。
regionMatches
public boolean regionMatches(int toffset, String other, int ooffset,
int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0)
|| (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
while (len-- > 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
判断两个字符串某个区域是否相等。
regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
public boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0)
|| (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
while (len-- > 0) {
char c1 = ta[to++];
char c2 = pa[po++];
if (c1 == c2) {
continue;
}
if (ignoreCase) {
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
// If the results match, then the comparison scan should
// continue.
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
return false;
}
return true;
}
指定是否忽略大小写,判断两个字符串某个区域是否相等。
startsWith(String prefix, int toffset)
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
测试此字符串的子字符串是否从指定的索引开始,以指定的前缀开头。
startsWith(String prefix)
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
测试此字符串是否以指定的前缀开头。
endsWith(String suffix)
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
测试此字符串是否以指定的后缀结束。
hashCode()
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
返回此字符串的哈希码值,若无,则通过计算创建。
indexOf(int ch)
public int indexOf(int ch) {
return indexOf(ch, 0);
}
返回指定字符首次出现的索引值。
indexOf(int ch, int fromIndex)
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);
}
}
返回第一次出现指定字符的字符串中的索引,从指定索引处开始搜索。
如果在此String对象所表示的字符序列中出现了具有值ch的字符,且索引为第一个不小于fromIndex的索引,则该索引。
lastIndexOf(int ch)
public int lastIndexOf(int ch) {
return lastIndexOf(ch, value.length - 1);
}
返回指定字符最后一次出现在此字符串中的索引。
lastIndexOf(int ch, int fromIndex)
public int lastIndexOf(int ch, int fromIndex) {
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;
int i = Math.min(fromIndex, value.length - 1);
for (; i >= 0; i--) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return lastIndexOfSupplementary(ch, fromIndex);
}
}
从指定的索引开始向后搜索,返回最后一次出现的指定字符在此字符串中的索引。
indexOf(String str)
public int indexOf(String str) {
return indexOf(str, 0);
}
返回指定的子字符串首次出现时在此字符串中的索引。
indexOf(String str, int fromIndex)
public int indexOf(String str, int fromIndex) {
return indexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
从指定的索引开始,返回第一次出现的指定子字符串在此字符串内的索引。
lastIndexOf(String str)
public int lastIndexOf(String str) {
return lastIndexOf(str, value.length);
}
返回指定的子字符串的最后一次出现在该字符串中的索引。
lastIndexOf(String str, int fromIndex)
public int lastIndexOf(String str, int fromIndex) {
return lastIndexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
从指定的索引开始向后搜索,返回指定的子字符串的最后一次出现在此字符串内的索引。
substring(int beginIndex)
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);
}
返回value从beginIndex开始到结束的子字符串。
substring(int beginIndex, int endIndex)
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);
}
返回value从beginIndex开始到endIndex的子字符串。
subSequence(int beginIndex, int endIndex)
public CharSequence subSequence(int beginIndex, int endIndex) {
return this.substring(beginIndex, endIndex);
}
返回此字符串从beginIndex开始到endIndex结束的字符序列。
concat(String str)
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
将指定的字符串连接到该字符串的末尾。
如果参数字符串的长度为0,则返回该String对象。否则,将返回String对象,该对象表示一个字符序列,该字符序列是此String对象表示的字符序列和参数字符串所表示的字符序列的串联。
replace(char oldChar, char newChar)
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;
}
返回一个字符串,该字符串是通过用newChar替换此字符串中所有出现的oldChar而产生的。
matches(String regex)
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
判断此字符串是否与给定的正则表达式匹配。
contains(CharSequence s)
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
当且仅当此字符串包含指定的字符值序列时,才返回true。
replaceFirst(String regex, String replacement)
public String replaceFirst(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
}
用给定的替换项替换与给定的正则表达式匹配的该字符串的第一个子字符串。
replaceAll(String regex, String replacement)
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
使用给定的替换项替换与给定的正则表达式匹配的该字符串的每个子字符串。
replace(CharSequence target, CharSequence replacement)
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
用指定的文字替换序列替换该字符串中与文字目标序列匹配的每个子字符串。 替换是从字符串的开头到结尾进行的。
split(String regex, int limit)
public String[] split(String regex, int limit) {
/* fastpath if the regex is a
(1)one-char String and this character is not one of the
RegEx's meta characters ".$|()[{^?*+\\", or
(2)two-char String and the first char is the backslash and
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
{
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, value.length));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}
在给定的正则表达式的匹配项周围拆分此字符串。
split(String regex)
public String[] split(String regex) {
return split(regex, 0);
}
在给定的正则表达式的匹配项周围拆分此字符串。
join(CharSequence delimiter, CharSequence… elements)
public static String join(CharSequence delimiter, CharSequence... elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
// Number of elements not likely worth Arrays.stream overhead.
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
返回一个新的String,该字符串由CharSequence元素的副本与指定的定界符的副本组成。
join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
public static String join(CharSequence delimiter,
Iterable<? extends CharSequence> elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
返回一个新的String,该字符串由CharSequence元素的副本与指定的定界符的副本组成。
toLowerCase(Locale locale)、toLowerCase()
public String toLowerCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
}
int firstUpper;
final int len = value.length;
/* Now check if there are any characters that need to be changed. */
scan: {
for (firstUpper = 0 ; firstUpper < len; ) {
char c = value[firstUpper];
if ((c >= Character.MIN_HIGH_SURROGATE)
&& (c <= Character.MAX_HIGH_SURROGATE)) {
int supplChar = codePointAt(firstUpper);
if (supplChar != Character.toLowerCase(supplChar)) {
break scan;
}
firstUpper += Character.charCount(supplChar);
} else {
if (c != Character.toLowerCase(c)) {
break scan;
}
firstUpper++;
}
}
return this;
}
char[] result = new char[len];
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */
/* Just copy the first few lowerCase characters. */
System.arraycopy(value, 0, result, 0, firstUpper);
String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] lowerCharArray;
int lowerChar;
int srcChar;
int srcCount;
for (int i = firstUpper; i < len; i += srcCount) {
srcChar = (int)value[i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE
&& (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent ||
srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
} else {
lowerChar = Character.toLowerCase(srcChar);
}
if ((lowerChar == Character.ERROR)
|| (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (lowerChar == Character.ERROR) {
lowerCharArray =
ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
} else if (srcCount == 2) {
resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
continue;
} else {
lowerCharArray = Character.toChars(lowerChar);
}
/* Grow result if needed */
int mapLen = lowerCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0, i + resultOffset);
result = result2;
}
for (int x = 0; x < mapLen; ++x) {
result[i + resultOffset + x] = lowerCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i + resultOffset] = (char)lowerChar;
}
}
return new String(result, 0, len + resultOffset);
}
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
}
使用给定的Locale的规则将此String中的所有字符转换为小写。大小写映射基于由java.lang.Character Character类指定的Unicode标准版本。
toUpperCase(Locale locale)、toUpperCase()
public String toUpperCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
}
int firstLower;
final int len = value.length;
/* Now check if there are any characters that need to be changed. */
scan: {
for (firstLower = 0 ; firstLower < len; ) {
int c = (int)value[firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE)
&& (c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR)
|| (c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
}
/* result may grow, so i+resultOffset is the write location in result */
int resultOffset = 0;
char[] result = new char[len]; /* may grow */
/* Just copy the first few upperCase characters. */
System.arraycopy(value, 0, result, 0, firstLower);
String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] upperCharArray;
int upperChar;
int srcChar;
int srcCount;
for (int i = firstLower; i < len; i += srcCount) {
srcChar = (int)value[i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent) {
upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
} else {
upperChar = Character.toUpperCaseEx(srcChar);
}
if ((upperChar == Character.ERROR)
|| (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (upperChar == Character.ERROR) {
if (localeDependent) {
upperCharArray =
ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
} else {
upperCharArray = Character.toUpperCaseCharArray(srcChar);
}
} else if (srcCount == 2) {
resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
continue;
} else {
upperCharArray = Character.toChars(upperChar);
}
/* Grow result if needed */
int mapLen = upperCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0, i + resultOffset);
result = result2;
}
for (int x = 0; x < mapLen; ++x) {
result[i + resultOffset + x] = upperCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i + resultOffset] = (char)upperChar;
}
}
return new String(result, 0, len + resultOffset);
}
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
使用给定的Locale的规则将此String中的所有字符转换为大写。大小写映射基于由java.lang.Character Character类指定的Unicode标准版本。
trim()
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
返回值是此字符串的字符串,其中已删除所有前导和尾随的空格。
toString()
public String toString() {
return this;
}
他的对象(已经是一个字符串!)本身就返回了。
toCharArray()
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
将此字符串转换为新的字符数组。
format(String format, Object… args)
public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
使用指定的格式字符串和参数返回格式化的字符串。
format(Locale l, String format, Object… args)
public static String format(Locale l, String format, Object... args) {
return new Formatter(l).format(format, args).toString();
}
使用指定的语言环境,格式字符串和参数,返回格式化后的字符串。
valueOf(Object obj)
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
返回Object参数的字符串表示形式。
valueOf(char data[])
public static String valueOf(char data[]) {
return new String(data);
}
返回char array 参数的字符串表示形式。字符数组的内容被复制;字符数组的后续修改不会影响返回的字符串。
valueOf(char data[], int offset, int count)
public static String valueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
以data[]的offset位置开始,向后累计count个字符为内容,创建字符串。
copyValueOf(char data[], int offset, int count)
public static String copyValueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
intern()
public native String intern();
返回字符串对象的规范表示。
小结
写String类的源码解析,绝大部分参考于源码上的注释,另加Google搜索的资料,虽然String的方法有很多,但其实有很多我们可以直接根据方法名猜出其功能作用,而且有些方法几乎不会用到,在阅读时,我们需要事先过滤掉不必要的!