搜尋
首頁Javajava教程java提高篇(十三)-----字串

java提高篇(十三)-----字串

Feb 10, 2017 am 11:22 AM
java字串

       可以證明,字串操作是電腦程式設計中最常見的行為。


      查看原始碼就會發現String類別為final型的(當然也不可被繼承),而且透過檢視JDK文件會發現幾乎每一個修改String物件的操作,其實都是建立了一個全新的String物件。

     

字串為對象,那麼在初始化之前,它的值為null,到這裡就有必要提下」”、null、new String()三者的區別。 null 表示string還沒有new ,也就是說物件的參考還沒有創建,也沒有分配記憶體空間給他,而」」、new String()則說明了已經new了,只不過內部為空,但是它創建了物件的引用,是需要分配記憶體空間的。打個比方:一個空玻璃杯,你不能說它裡面什麼都沒有,因為裡面有空氣,當然也可以把它弄成真空,null與" "、new String()的區別會檢查字串池中是否存在面值相等的字串,如果有,則不再創建,直接放回字串池中對該物件的引用,若沒有則創建然後放入到字串池中並且返回新建物件的參考。會新建一個String物件(即String s = new String(”aa”))。

     

對字串的使用無非就是這幾個面向:

      

equals() ------判斷內容是否相同。

        

compareTo() ------判斷字串的大小關係。          compareToIgnoreCase(String int) ------比較時忽略字母大小寫。

         == ------判斷內容物與位址是否相同。

         equalsIgnoreCase() ------在忽略大小寫的情況下判斷內容是否相同。

         reagionMatches() ------是否為字串中的部分內容相同(詳情請參考API)。

     

2、字串尋找

       

       

    

         indexOf(String str)------從字串開始擷取str,並傳回第一次出現的位置,未出現回傳-1。

         indexOf(String str,int fromIndex);------從字串的第fromIndex個字元開始擷取str。

         lastIndexOf(String str)------找出最後一次出現的位置。

         lastIndexOf(String str,int fromIndex)----從字串的第fromIndex個字元找出最後一次出現的位置。

         starWith(String prefix,int toffset)-----測試此字串從指定索引開始的子字串是否以指定前綴開始。

         starWith(String prefix)------測試此字串是否以指定的前綴開始。

         endsWith(String suffix)------測試此字串是否以指定的後綴結束。

     3、字串截斷

字串,它是此字串的一個子字串。

        

public String subString(int beginIndex,int endIndex)------傳回的字串是從beginIndex開始到endIndex-1的字串。

     4、字串替換

     

        

public String replace(CharSequence target,CharSequence replacement)------把原來的etarget子序列替換為replacement序列,回新串連。

        

public String replaceAll(String regex,String replacement)------以正規表示式實作字串的符合。注意replaceAll第一個參數為正規表示式,而鄙人曾經深受其害。

     5、更多方法請參考API StringBuffer

      StringBuffer和String一樣都是用來儲存字符串的,只不過由於他們內部的實作方式不同,導致他們所使用的範圍不同,對於StringBuffer而言,他在處理字串時,若是對其進行修改操作,它並不會產生一個新的字串對象,所以說在記憶體使用方面它是優於String的。
     

其實在使用方法,StringBuffer的許多方法和String類別都差不多,表示的功能幾乎一模一樣,只不過在修改時StringBuffer都是修改自身,而String類別則是產生一個新的對象,這是他們之間最大的區別。

      同時StringBuffer是不能使用=初始化的,它必須產生StringBuffer實例,也就是說你必須透過它的建構方法來初始化。

      在StringBuffer的使用方面,它更著重於字串的變化,例如追加、修改、刪除,對應的方法:目前StringBuffer物件的結尾,類似字串的連接,這裡StringBuffer物件的內容會改變。

      2、insert:此類別方法主要在StringBuffer物件中插入內容。

      3、delete:此類別主要用於移除StringBuffer物件中的內容。

      三、StringBuilder

      String,它也是一個不規範的對象,他與它是不同的字串相比較之處,這一點就比它不相一致的對象,他與它是不同的對象,他與它是不同相的對象,這一點就比它不相結合的對象,他與它相同的相似性,他與它相同的點相匹配。 StringBuffer快。與StringBuffer一樣,StringBuider的主要操作也是append與insert方法。這兩個方法都能有效地將給定的資料轉換成字串,然後將該字串的字元新增或插入到字串產生器中。

      上面只是簡單的介紹了String、StringBuffer、StringBuilder,其實對於這三者我們應該更專注於他們只見到的區別,只有理清楚他們之間的區別才能夠更好的使用他們。


     四、正確使用String、StringBuffer 我們先看如下表:

     
這裡對於String是否為線程安全,鄙人也不是很清楚,原因:String不可變,所有的操作都是不可能改變其值的,是否存在線程安全一說還真不好說?但是如果硬要說線程是否安全的話,因為內容不可變,永遠都是安全的。


     

在使用方面由於String每次修改都需要產生一個新的對象,所以對於經常需要改變內容的字符串最好選擇StringBuffer或者StringBuilder.而對於StringBuffer,每次操作都是對StringBuffer對象本身,它不會產生新的對象,所以StringBuffer特別適用於字串內容經常改變的情況。

     

但是並不是所有的String字串運算都會比StringBuffer慢,在某些特殊的情況下,String字串的拼接會被JVM解析成StringBuilder物件,在這個情況下String的速度比StringBuffer的速度快。如:

     

String name = ”I ” + ”am ” + ”chenssy ” ; ).append(” chenssy ”);

      對於這兩種方式,你會發現第一種比第二種快太多了,在這裡StringBuffer的優勢蕩然無存。其實的原因就在於JVM做了一下優化處理,其實String name = ”I ” + ”am ” + ”chenssy ” ;在JVM眼中就是String name = ”I am chenssy ” ;這樣的方式對於JVM而言,真的是不要什麼時間。但是如果我們在這個其中增加一個String對象,那麼JVM就會按照原來那種規範來建構String物件了。

      對於這三者使用的場景做以下概括(參考:《寫出搞品質程式碼:改善java程式的151個建議》):

變化的場景中可以使用String類,如:常數的聲明、少量的變數運算等。

        

2、StringBuffer:在頻繁的字串的運算(拼接、解析、刪除等),且執行在多重執行緒的環境中,則可考慮使用封裝Buffer,例如XML、解析、TPTP等。

        

3、StringBuilder:在頻繁進行字串的運算(拼接、替換、刪除等),並且運行在多執行緒的環境中,可以考慮使用StringBuffer,如SQL、替換、刪除等),並且在多執行緒的環境中運行(貌似這兩個我也是使用|StringBuffer)。

      更多關於他們之間區別,請參考:http://www.php.cn/。鄙人就不畫蛇添足了。

      五、字符串拼接方式

  、concat()以及append()方法。這三者之間有什麼差別呢?先看以下範例:

public class StringTest {
    
    /**
     * @desc 使用+、concat()、append()方法循环10W次
     * @author chenssy
     * @data 2013-11-16
     * @param args
     * @return void
     */
    public static void main(String[] args) {
        //+
        long start_01 = System.currentTimeMillis();
        String a = "a";
        for(int i = 0 ; i < 100000 ; i++){
            a += "b";
        }
        long end_01 = System.currentTimeMillis();
        System.out.println("  +   所消耗的时间:" + (end_01 - start_01) + "毫米");
        
        //concat()
        long start_02 = System.currentTimeMillis();
        String c = "c";
        for(int i = 0 ; i < 100000 ; i++){
            c = c.concat("d");
        }
        long end_02 = System.currentTimeMillis();
        System.out.println("concat所消耗的时间:" + (end_02 - start_02) + "毫米");
        
        //append
        long start_03 = System.currentTimeMillis();
        StringBuffer e = new StringBuffer("e");
        for(int i = 0 ; i < 100000 ; i++){
            e.append("d");
        }
        long end_03 = System.currentTimeMillis();
        System.out.println("append所消耗的时间:" + (end_03 - start_03) + "毫米");
    }
}

------------
Output:
  +   所消耗的时间:19080毫米
concat所消耗的时间:9089毫米
append所消耗的时间:10毫米



public class StringTest {    
    /**
     * @desc 使用+、concat()、append()方法循环10W次
     * @author chenssy
     * @data 2013-11-16
     * @param args
     * @return void     */
    public static void main(String[] args) {        //+
        long start_01 = System.currentTimeMillis();
        String a = "a";        for(int i = 0 ; i 

🠎

public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    char buf[] = new char[count + otherLen];
    getChars(0, count, buf, 0);
    str.getChars(0, otherLen, buf, count);
    return new String(0, count + otherLen, buf);
    }


)app原因請看下面分解:

     

(一)+方式拼接字串

Builder的append ()方法來進行處理的,我們知道StringBuilder的速度比StringBuffer的速度更快,但是為何運行速度還是那樣呢?主要是因為編譯器使用append()方法追加後要同toString()轉換成String字串,也就說str +=”b」等同於

      str = new StringBuilder(str).append( "b").toString();

      它變慢的關鍵原因就在於new StringBuilder()和toString(),這裡可是創建了10W個StringBuilder物件,而且每次還需要將其轉換成String,速度能不慢麼?

     (二)concat()方法拼接字串

      這是concat()的原始碼,它看起來就是一個數字拷貝形式,我們知道數組的處理速度是非常快的,但是由於該方法最後是這樣的:return new String(0, count + otherLen, buf);這同樣也創建了10W個字符串對象,這是它變慢的根本原因。



     

(三)append()方法拼接字串

方法是​​直接使用父類別AbstractStringBuilder的append()方法,該方法的來源碼如下:

public synchronized StringBuffer append(String str) {    super.append(str);        return this;
    }

     

與concat()方法相似,它也是進行字符數組處理的,然後加總長度將它返回一個長新串,而是回傳本身,也就說這這個10W次的循環過程中,它並沒有產生新的字串物件。

     

透過上面的分析,我們需要在適當的場所選擇合適的字串拼接方式,但是不一定就要選擇append()和concat()方法,原因在於+根據符合我們的程式設計習慣,只有到了使用append()和concat()方法確實是可以對我們系統的效率起到比較大的幫助,才會考慮,同時鄙人也真的沒有怎麼用過concat()方法。

以上就是java提高篇(十三)-----字串 的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
是否有任何威脅或增強Java平台獨立性的新興技術?是否有任何威脅或增強Java平台獨立性的新興技術?Apr 24, 2025 am 12:11 AM

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

JVM的實現是什麼,它們都提供了相同的平台獨立性?JVM的實現是什麼,它們都提供了相同的平台獨立性?Apr 24, 2025 am 12:10 AM

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性如何降低發展成本和時間?平台獨立性如何降低發展成本和時間?Apr 24, 2025 am 12:08 AM

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java的平台獨立性如何促進代碼重用?Java的平台獨立性如何促進代碼重用?Apr 24, 2025 am 12:05 AM

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

您如何在Java應用程序中對平台特定問題進行故障排除?您如何在Java應用程序中對平台特定問題進行故障排除?Apr 24, 2025 am 12:04 AM

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

JVM中的類加載程序子系統如何促進平台獨立性?JVM中的類加載程序子系統如何促進平台獨立性?Apr 23, 2025 am 12:14 AM

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器會產生特定於平台的代碼嗎?解釋。Java編譯器會產生特定於平台的代碼嗎?解釋。Apr 23, 2025 am 12:09 AM

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

JVM如何處理不同操作系統的多線程?JVM如何處理不同操作系統的多線程?Apr 23, 2025 am 12:07 AM

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中