Java反轉字符串和相干字符編碼的成績處理。本站提示廣大學習愛好者:(Java反轉字符串和相干字符編碼的成績處理)文章只能為提供參考,不一定能成為您想要的結果。以下是Java反轉字符串和相干字符編碼的成績處理正文
public String reverse(char[] value){
for (int i = (value.length - 1) >> 1; i >= 0; i--){
char temp = value[i];
value[i] = value[value.length - 1 - i];
value[value.length - 1 - i] = temp;
}
return new String(value);
}
如許的代碼,在算法方面是沒有任何成績的。然則明天在檢查StringBuffer源代碼的時刻發明,個中reverse辦法的源代碼寫的很精巧。源代碼以下:
public AbstractStringBuilder reverse() {
boolean hasSurrogate = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; --j) {
char temp = value[j];
char temp2 = value[n - j];
if (!hasSurrogate) {
hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
|| (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
}
value[j] = temp2;
value[n - j] = temp;
}
if (hasSurrogate) {
// Reverse back all valid surrogate pairs
for (int i = 0; i < count - 1; i++) {
char c2 = value[i];
if (Character.isLowSurrogate(c2)) {
char c1 = value[i + 1];
if (Character.isHighSurrogate(c1)) {
value[i++] = c1;
value[i] = c2;
}
}
}
}
return this;
}
這個辦法是界說在StringBuffer的父類AbstractStringBuilder中的,所以該辦法的前往值是AbstractStringBuilder,在子類中挪用的方法以下:
public synchronized StringBuffer reverse() {
super.reverse();
return this;
}
從辦法的內容來看,源代碼中的根本思緒是分歧的,異樣采取遍歷一半字符串,然後將每一個字符與其對應的字符停止交流。然則有分歧的地方,就是要斷定每一個字符能否在Character.MIN_SURROGATE(\ud800)和Character.MAX_SURROGATE(\udfff)之間。假如發明全部字符串中含有這類情形,則再次從頭到尾遍歷一次,同時斷定value[i]能否知足Character.isLowSurrogate(),假如知足的情形下,持續斷定value[i+1]能否知足Character.isHighSurrogate(),假如也知足這類情形,則將第i位和第i+1位的字符交換。能夠有的人會困惑,為何要這麼做,由於Java中的字符曾經采取Unicode代碼,每一個字符可以放下一個漢字。為何還要這麼做?
一個完全的 Unicode 字符叫代碼點CodePoint,而一個 Java char 叫 代碼單位 code unit。String 對象以UTF-16保留 Unicode 字符,須要用2個字符表現一個超年夜字符集的漢字,這這類表現方法稱之為 Surrogate,第一個字符叫 Surrogate High,第二個就是 Surrogate Low。詳細須要留意的事宜以下:
斷定一個char能否是Surrogate區的字符,用Character的 isHighSurrogate()/isLowSurrogate()辦法便可斷定。從兩個Surrogate High/Low 字符,前往一個完全的 Unicode CodePoint 用 Character.toCodePoint()/codePointAt()辦法。
一個Code Point,能夠須要一個也能夠須要兩個char表現,是以不克不及直接應用 CharSequence.length()辦法直接前往一個字符串究竟有若干個漢字,而須要用String.codePointCount()/Character.codePointCount()。
要定位字符串中的第N個字符,不克不及直接將N作為偏移量,而須要從字符串頭部順次遍歷獲得,須要用String/Character.offsetByCodePoints() 辦法。
從字符串確當前字符,找到上一個字符,也不克不及直接用offset-- 完成,而須要用 String.codePointBefore()/Character.codePointBefore(),或用 String/Character.offsetByCodePoints()
從以後字符,找下一個字符,不克不及直接用 offset++完成,須要斷定以後 CodePoint的長度後,再盤算獲得,或用String/Character.offsetByCodePoints()。