欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java反轉(zhuǎn)字符串和相關(guān)字符編碼的問題解決

 更新時(shí)間:2013年05月27日 10:34:10   作者:  
反轉(zhuǎn)字符串一直被當(dāng)作是簡單問題,大家的思想主要就是利用遍歷,首尾交換字符實(shí)現(xiàn)字符串的反轉(zhuǎn)。例如下面的代碼,就可以簡單實(shí)現(xiàn)反轉(zhuǎn)。

復(fù)制代碼 代碼如下:

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源代碼的時(shí)候發(fā)現(xiàn),其中reverse方法的源代碼寫的很精妙。源代碼如下:

復(fù)制代碼 代碼如下:

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;
 }

這個(gè)方法是定義在StringBuffer的父類AbstractStringBuilder中的,所以該方法的返回值是AbstractStringBuilder,在子類中調(diào)用的方式如下:
復(fù)制代碼 代碼如下:

public synchronized StringBuffer reverse() {
    super.reverse();
    return this;
}

從方法的內(nèi)容來看,源代碼中的基本思路是一致的,同樣采用遍歷一半字符串,然后將每個(gè)字符與其對(duì)應(yīng)的字符進(jìn)行交換。但是有不同之處,就是要判斷每個(gè)字符是否在Character.MIN_SURROGATE(\ud800)和Character.MAX_SURROGATE(\udfff)之間。如果發(fā)現(xiàn)整個(gè)字符串中含有這種情況,則再次從頭至尾遍歷一次,同時(shí)判斷value[i]是否滿足Character.isLowSurrogate(),如果滿足的情況下,繼續(xù)判斷value[i+1]是否滿足Character.isHighSurrogate(),如果也滿足這種情況,則將第i位和第i+1位的字符互換??赡苡械娜藭?huì)疑惑,為什么要這么做,因?yàn)镴ava中的字符已經(jīng)采用Unicode代碼,每個(gè)字符可以放下一個(gè)漢字。為什么還要這么做?
一個(gè)完整的 Unicode 字符叫代碼點(diǎn)CodePoint,而一個(gè) Java char 叫 代碼單元 code unit。String 對(duì)象以UTF-16保存 Unicode 字符,需要用2個(gè)字符表示一個(gè)超大字符集的漢字,這這種表示方式稱之為 Surrogate,第一個(gè)字符叫 Surrogate High,第二個(gè)就是 Surrogate Low。具體需要注意的事宜如下:
判斷一個(gè)char是否是Surrogate區(qū)的字符,用Character的 isHighSurrogate()/isLowSurrogate()方法即可判斷。從兩個(gè)Surrogate High/Low 字符,返回一個(gè)完整的 Unicode CodePoint 用 Character.toCodePoint()/codePointAt()方法。
  一個(gè)Code Point,可能需要一個(gè)也可能需要兩個(gè)char表示,因此不能直接使用 CharSequence.length()方法直接返回一個(gè)字符串到底有多少個(gè)漢字,而需要用String.codePointCount()/Character.codePointCount()。
 要定位字符串中的第N個(gè)字符,不能直接將N作為偏移量,而需要從字符串頭部依次遍歷得到,需要用String/Character.offsetByCodePoints() 方法。
從字符串的當(dāng)前字符,找到上一個(gè)字符,也不能直接用offset-- 實(shí)現(xiàn),而需要用 String.codePointBefore()/Character.codePointBefore(),或用 String/Character.offsetByCodePoints()
 從當(dāng)前字符,找下一個(gè)字符,不能直接用 offset++實(shí)現(xiàn),需要判斷當(dāng)前 CodePoint的長度后,再計(jì)算得到,或用String/Character.offsetByCodePoints()。

相關(guān)文章

  • SpringBoot啟動(dòng)器Starters使用及原理解析

    SpringBoot啟動(dòng)器Starters使用及原理解析

    這篇文章主要介紹了SpringBoot啟動(dòng)器Starters使用及原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot項(xiàng)目配置明文密碼泄露問題的處理方式

    SpringBoot項(xiàng)目配置明文密碼泄露問題的處理方式

    這篇文章主要介紹了SpringBoot項(xiàng)目配置明文密碼泄露問題的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java?Scanner?類讀取一維數(shù)組二維數(shù)組示例詳解

    Java?Scanner?類讀取一維數(shù)組二維數(shù)組示例詳解

    這篇文章主要為大家介紹了Java?Scanner?類讀取一維數(shù)組二維數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Spring Cloud服務(wù)安全連接方式

    Spring Cloud服務(wù)安全連接方式

    這篇文章主要介紹了Spring Cloud服務(wù)安全連接方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringMVC前端和后端數(shù)據(jù)交互總結(jié)

    SpringMVC前端和后端數(shù)據(jù)交互總結(jié)

    本篇文章主要介紹了SpringMVC前端和后端數(shù)據(jù)交互總結(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • SpringCloud超詳細(xì)講解負(fù)載均衡組件Ribbon源碼

    SpringCloud超詳細(xì)講解負(fù)載均衡組件Ribbon源碼

    在微服務(wù)中,對(duì)服務(wù)進(jìn)行拆分之后,必然會(huì)帶來微服務(wù)之間的通信需求,而每個(gè)微服務(wù)為了保證高可用性,又會(huì)去部署集群,那么面對(duì)一個(gè)集群微服務(wù)進(jìn)行通信的時(shí)候,如何進(jìn)行負(fù)載均衡也是必然需要考慮的問題
    2022-07-07
  • Spring基于XML實(shí)現(xiàn)Aop

    Spring基于XML實(shí)現(xiàn)Aop

    這篇文章主要介紹了Spring中基于xml的AOP的詳細(xì)步驟,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • java入門概念個(gè)人理解之package與import淺析

    java入門概念個(gè)人理解之package與import淺析

    下面小編就為大家?guī)硪黄猨ava入門概念個(gè)人理解之package與import淺析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • formfile文件上傳使用示例

    formfile文件上傳使用示例

    這篇文章主要介紹了formfile文件上傳使用示例,代碼已加注釋,需要的朋友可以參考下
    2014-03-03
  • Java 生成圖片驗(yàn)證碼3種方法(字母、加減乘除、中文)

    Java 生成圖片驗(yàn)證碼3種方法(字母、加減乘除、中文)

    這篇文章主要介紹了Java 生成圖片驗(yàn)證碼3種方法(字母、加減乘除、中文),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01

最新評(píng)論