天天看點

[Java開發之路](2)Java字元串

1.什麼是java中的字元串

在 java 中,字元串被作為 string 類型的對象處理。 string 類位于 java.lang 包中。預設情況下,該包被自動導入所有的程式。

建立 string 對象的方法:

<code>package com.qunar.test;</code>

<code> </code>

<code>public class helloworld {</code>

<code></code>

<code>public static void main(string[] args){</code>

<code>// 建立一個字元串對象</code>

<code>string str = "xiaosi";</code>

<code>// 建立一個空字元串對象</code>

<code>string str2 = new string();</code>

<code>string str3 = new string("i am from china");</code>

<code>system.out.println("str-&gt;"+str);</code>

<code>system.out.println("str2-&gt;"+str2);</code>

<code>system.out.println("str3-&gt;"+str3);</code>

<code>}</code>

2. java字元串的不變性

string 對象建立後則不能被修改,是不可變的,所謂的修改其實是建立了新的對象,所指向的記憶體空間不同。如下所示:

<code>string str1 = "xiaosi";</code>

<code>string str2 = "xiaosi";</code>

<code>string str4 = new string("i am from china");</code>

<code>// str1 str2 是字元串常量 java編譯程式隻建立一個 str1 str2 指向同一個對象</code>

<code>system.out.println("str1 == str2 "+(str1 == str2)); // true</code>

<code>// str1 str2是不同的對象</code>

<code>system.out.println("str1 == str3 "+(str1 == str3)); // false</code>

<code>// str3 str4是不同的對象</code>

<code>system.out.println("str3 == str4 "+(str3 == str4)); // false</code>

<code>str1 = "歡迎你 " + str1;</code>

<code>system.out.println("str1-&gt;"+str1); // 歡迎你 xiaosi</code>

對于str1字元串看似修改了其值:(xiaosi  -&gt;   歡迎你 xiaosi)

但其實不是表面那樣,str1實際上不在指向值為xiaosi的對象,而是指向了值為“歡迎你 xiaosi”對象上(新建立了一個對象)。

這樣做是否會降低運作效率呢?看起來好像修改一個代碼單元要比建立一個新字元串更加簡介。答案是:也對,也不對。通過拼接"歡迎你"和"xiaosi"來建立一個新字元串的效率确實不高。但是,不可變字元卻有一個有點:編譯器可以讓字元串達到共享。

為了弄清楚具體的工作方式,可以想象将各種字元串放入公共的字元串存儲池中,字元串變量指向字元串存儲池中相應位置。如果複制一個字元串變量,原始字元串與複制的字元串變量共享相同的字元。

java設計者認為共享帶來的高效率遠遠勝于提取,拼接字元串所帶來的低效率。檢視一下程式你就會發現:很少需要修改字元串,而是往往需要對字元串進行比較。

當str1重新指向一個新生成的對象時,你會不會想:這樣做會不會産生記憶體洩露呢?畢竟,原始字元串放置在堆中。對于這樣的情況,java設計者已經想到,java将會自動進行垃圾回收,如果一塊記憶體不在使用了,系統将會将其回收。

3.java中字元串常用方法

string 類提供了許多用來處理字元串的方法,例如,擷取字元串長度、對字元串進行截取、将字元串轉換為大寫或小寫、字元串分割等,下面我們就來領略它的強大之處吧。

[Java開發之路](2)Java字元串

案例:

<code>public static void main(string[] args) {</code>

<code>// java檔案名</code>

<code>string filename = "helloworld.jav";</code>

<code>// 郵箱</code>

<code>string email = "[email protected]";</code>

<code>// 判斷.java檔案名是否正确:合法的檔案名應該以.java結尾</code>

<code>/*</code>

<code>參考步驟:</code>

<code>1、擷取檔案名中最後一次出現"."号的位置</code>

<code>2、根據"."号的位置,擷取檔案的字尾</code>

<code>3、判斷"."号位置及檔案字尾名</code>

<code>*/</code>

<code>//擷取檔案名中最後一次出現"."号的位置</code>

<code>int index = filename.lastindexof('.');</code>

<code>// 擷取檔案的字尾</code>

<code>string prefix = filename.substring(index+1);</code>

<code>// 判斷必須包含"."号,且不能出現在首位,同時字尾名為"java"</code>

<code>if (index != -1 &amp;&amp; index != 0 &amp;&amp; prefix.equals("java")) {</code>

<code>system.out.println("java檔案名正确");</code>

<code>} else {</code>

<code>system.out.println("java檔案名無效");</code>

<code>// 判斷郵箱格式是否正确:合法的郵箱名中至少要包含"@", 并且"@"是在"."之前</code>

<code>1、擷取檔案名中"@"符号的位置</code>

<code>2、擷取郵箱中"."号的位置</code>

<code>3、判斷必須包含"@"符号,且"@"必須在"."之前</code>

<code>// 擷取郵箱中"@"符号的位置</code>

<code>int index2 = email.indexof('@');</code>

<code>// 擷取郵箱中"."号的位置</code>

<code>int index3 = email.indexof('.');</code>

<code>// 判斷必須包含"@"符号,且"@"必須在"."之前</code>

<code>if (index2 != -1 &amp;&amp; index3 &gt; index2) {</code>

<code>system.out.println("郵箱格式正确");</code>

<code>system.out.println("郵箱格式無效");</code>

<code>// 定義一個字元串</code>

<code>string s = "aljlkdsflkjsadjfklhasdkjlflkajdflwoiudsafhaasdasd";</code>

<code>// 出現次數</code>

<code>int num = 0;</code>

<code>// 循環周遊每個字元,判斷是否是字元 a ,如果是,累加次數</code>

<code>for (int i = 0;i &lt; s.length();++i)</code>

<code>{</code>

<code>// 擷取每個字元,判斷是否是字元a</code>

<code>if (s.charat(i) == 'a') {</code>

<code>// 累加統計次數</code>

<code>num++;</code>

<code>system.out.println("字元a出現的次數:" + num);</code>

[Java開發之路](2)Java字元串

3. == 和 equals差別

==: 判斷兩個字元串在記憶體中首位址是否相同,即判斷是否是同一個字元串對象

equals(): 比較存儲在兩個字元串對象中的内容是否一緻

4.stringbuilder 類

在java中,除了可以使用 string 類來存儲字元串,還可以使用 stringbuilder 類或 stringbuffer 類存儲字元串,那麼它們之間有什麼差別呢?

<code>system.out.println(str + " hello");</code>

<code>system.out.println(str);</code>

運作結果:

<code>xiaosi hello</code>

<code>xiaosi</code>

從運作結果中我們可以看到,程式運作時會額外建立一個對象,儲存 "xiaosi hello"。當頻繁操作字元串時,就會額外産生很多臨時變量。使用 stringbuilder 或 stringbuffer 就可以避免這個問題。至于 stringbuilder 和stringbuffer ,它們基本相似,不同之處,stringbuffer 是線程安全的,而 stringbuilder

則沒有實作線程安全功能,是以性能略高。是以一般情況下,如果需要建立一個内容可變的字元串對象,應優先考慮使用 stringbuilder 類。

那麼如何定義 stringbuilder 類的對象呢? 我們來看下面的代碼:

<code>stringbuilder str = new stringbuilder("xiaosi");</code>

stringbuilder 類提供了很多方法來操作字元串:

[Java開發之路](2)Java字元串

例如:在下面的示例代碼中,建立了 stringbuilder 對象,用來存儲字元串,并對其做了追加和插入操作。這些操作修改了 str 對象的值,而沒有建立新的對象,這就是 stringbuilder 和 string 最大的差別。

<code>// 建立一個空的stringbuilder對象</code>

<code>stringbuilder str = new stringbuilder();</code>

<code>// 追加字元串</code>

<code>str.append("jaewkjldfxmopzdm");</code>

<code>// 從後往前每隔三位插入逗号</code>

<code>for (int i = str.length()-3;i &gt; 0;i = i - 3){</code>

<code>str.insert(i,',');</code>

<code>// 将stringbuilder對象轉換為string對象并輸出</code>

<code>system.out.print(str.tostring());</code>