記錄下閱讀源碼過程中遇到的有用的知識
1.String位final類,不可繼承,其聲明爲
public final class String
private char value[]`存儲.
implements java.io.Serializable, Comparable<String>, CharSequence,String的內容由
2.方法public int codePointAt(int index)
直接返回索引下的char元素的Unicode code point,如
String Str = "012345Str";
//直接返回索引下的char元素的Unicode code point
System.out.println(Str.codePointAt(0));
可以得到0的Unicode code point爲48,這樣獲得字母數字和特殊符號的ASCII碼很方便。
源碼實現爲:
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
3.函數public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)可以將String截取某部分放到char []中,函數的實現方法爲
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);
}
還不如先使用substring()截取某一段,再使用toCharArray()轉換成char[]更加方便。
4.重寫equals方法
public boolean equals(Object anObject) {
if (this == anObject) {//當前要比較對象爲同一對象,返回true,滿足自反性
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;
}
5.String類對compareTo方法的實現方法
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);//以最小長度的string爲基準
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;//返回值爲第一個不等char元素的差值
}
k++;
}
return len1 - len2;//返回值爲兩個String的長度差
}
當然,這種版本的compareTo方法不會令所有人滿意,比如我就不太滿意,哈哈。
6.startsWith(String prefix,int rooffset)方法.該方法用於判斷String是否以prefix爲前綴,這個方法實現起來比較簡單。
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;
}
public boolean endsWith(String suffix) 判斷String是否以suffix爲後綴,直接調用startsWith就可以了。
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
7.重寫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;
}
使用了一個簡單的多項式散列函數算出了hash值,簡單的hash函數可以降低計算開銷,加快程序速度(在滿足hash要求的前提下),由 h = 31 * h + val[i]可以看出,不同的String完全有可能具有相同的hashCode,所以只根據hashCode值相同不能說明兩個String相等,需要通過equals()方法才能準確地判斷。
8.字符串連接函數contact()
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);
}
做字符串連接時比較方便
String Str = "012345Str";
System.out.println(Str.concat(" I love Java"));
9.字符替換函數repalce(char oldChar,char newChar),用於將String中所有的oldChar替換爲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;
}
10.正則表達式匹配函數public boolean matches(String regex).
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
如:
String str = "[email protected]";
// 郵箱驗證規則
String regEx = "[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";
// 編譯正則表達式
System.out.println(str.matches(regEx));
打印結果爲true.
11.正則表達式替換函數replaceAll(String regex, String replacement)
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
12.String的最後一個方法就是public native String intern();方法了,方法的作用javadoc裏說得很清楚:
/**
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings.
*/
還沒找到intern()的源碼,哈哈