Java String, StringBuffer和StringBuilder實例

1- 分層繼承


當使用文本數據時,Java提供了三種類別,包括String, StringBuffer和StringBuilder。當使用大數據來工做時,你應該用StringBuffer或StringBuilder來優化效率。基本上這三個類有許多類似之處。
  • String 是不可變的(這個概念的更多詳細信息,在文檔中)。它不容許子類的存在。
  • StringBuffer, StringBuilder 是可變的。
StringBuilder和StringBuffer都是同樣的,除了涉及到多線程的使用狀況。
  • 爲了處理多線程使用文本,你應該爲了防止線程之間衝突而使用StringBuffer。
  • 要使用一個線程處理的文本,你應該使用StringBuilder。
至於處理的速度,StringBuilder是最好的,其次是StringBuffer,而最後是String。

2- 可變和不可變的概念

考慮下面的一個例子:
// This is a class with value field and name field.
// When you create this class, you cannot reset the value and all other fields from outside.
// This class does not have methods for the purpose of resetting fields from outside.
// It means this class is immutable
public class ImmutableClassExample  {
   private int value;
   private String name;

   public ImmutableClassExample(String name, int value)  {
          this.value = value;
          this.name= name;
   }

   public String getName()  {
          return name;
   }

   public int getValue()  {
         return value;
   }
}


// This is a class owning a value field.
// After creating the object, you can reset values of the value field by calling setNewValue(int) method.
// This is a mutable class.
public class MutableClassExample  {

     private int value;

     public MutableClassExample(int value)  {
           this.value= value;
     }

     public void setNewValue(int newValue)  {
          this.value = newValue;
     }

}
String是不可變的類。String包括各類字段如長度,但在這些字段中的值不能改變。

3- String

String 在Java中是最重要的一個類,Java編程開始使用字符串就使用著名的System.out.println()語句在控制檯上打印東西。許多Java初學者不知道String是不可變的和最終的Java字符串結果,每次修改須要建立一個新的String對象。

3.1- String是一個很是特殊的類

字符串接受Java的特殊處理,由於它們在程序中常用。所以,效率(在計算和存儲方面)是相當重要的。
Java的設計者決定這一個面嚮對象語言,以保留原始類型,而不是使全部的對象, 以便提升語言的性能。原始數據存儲(在)調用棧,其須要較少的存儲空間和更方便的操做。另外一方面,對象被存儲在程序堆,這須要複雜的存儲器管理和更多的存儲空間。出於性能的緣由,Java字符串被設計爲在一種原始和類之間類型。特殊功能的字符串包括:
  1. 「+」操做符,它執行的加入對原始類型(如int和double),重載對String對象進行操做。'+'兩個字符串操做數進行串聯。 Java不考慮讓開發者支持運算符重載。在支持運算符重載像C++語言,能夠把一個「+」操做符來執行減法,引發不良代碼。 「+」操做符是重載的內部支持字符串鏈接在Java中的惟一操做符。注意到,「+」不在兩個任意對象上工做。
  2. 一個字符串,能夠經過構造:
    • 直接分配字符串到字符串引用 - 就像一個原始數據類型或經過「new」操做符和構造,相似於任何其餘類。然而,這是不經常使用的,因此不推薦。
  3. 字符串字面存儲在一個公共池。這有利於對具備相同內容的字符串,以節省存儲存儲的共享。new操做符分配的String對象都存儲在堆中,並無對相同內容的共享存儲。
例如:
// Implicit construction via string literal
String str1 = "Java is Hot";

// Explicit construction via new
String str2 = new String("I'm cool");
 

3.2- String文字和String對象

正如前面提到的,有兩種方法來構造字符串:經過指定一個字符串字面量或顯式建立經過 new 操做符,並構造一個String對象的隱式構建。 例如,
String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object
咱們使用如下圖片說明來解釋它:
Java已經提供了一個特殊的機制,來保存字符串文字 - 所謂的字符串公共池。若是兩個字符串具備相同的內容,它們將共享公共池內同一存儲器。這樣的作法是採起以節省對常用的字符串存儲。在另外一方面,經過 new 操做符和構造器建立String對象都保存在堆中。 在堆中的每一個String對象都有本身的存儲就像任何其餘對象。沒有共享存儲堆,即便兩個String對象具備相同的內容。
可使用String類的方法equals()方法比較兩個字符串的內容。可使用關係等於運算符'=='來比較兩個對象的引用(或指針)。研究如下代碼:
String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

s1 == s1;         // true, same pointer
s1 == s2;         // true, s1 and s2 share storage in common pool
s1 == s3;         // true, s3 is assigned same pointer as s1
s1 == s4;         // false, different pointers
s4 == s5;         // false, different pointers in heap

s1.equals(s3);    // true, same contents
s1.equals(s4);    // true, same contents
s4.equals(s5);    // true, same contents
事實上,你應該使用字符串,而是採用了「new」的操做符,這有助於加快程序運行速度。

3.3- 字符串的方法

下面是字符串列表的方法:
SN 方法 描述
1 char charAt(int index)
返回指定索引處的字符
2 int compareTo(Object o)
該字符串的另外一個對象比較
3 int compareTo(String anotherString)
字典順序比較兩個字符串
4 int compareToIgnoreCase(String str)
按字典順序比較兩個字符串,忽略大小寫差別
5 String concat(String str)
將指定字符串添加到該字符串的結尾處
6 boolean contentEquals(StringBuffer sb)
當且僅當此String表示字符與指定StringBuffer的順序相同時返回true
7 static String copyValueOf(char[] data)
返回表示所指定的數組中的字符序列的字符串
8 static String copyValueOf(char[] data, int offset, int count)
返回表示所指定的數組中的字符序列的字符串
9 boolean endsWith(String suffix)
測試此字符串是否以指定的後綴結束
10 boolean equals(Object anObject)
比較此字符串指定的對象
11 boolean equalsIgnoreCase(String anotherString)
這個字符串與另外一個字符串比較,不考慮大小寫
12 byte getBytes()
將此String使用平臺默認的字符集的字節序列解碼,並將結果存儲到一個新的字節數組
13 byte[] getBytes(String charsetName)
將此String使用指定字符集的字節序列解碼,並將結果存儲到一個新的字節數組
14 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
將這個字符串的字符複製到目標字符數組
15 int hashCode()
返回此字符串的哈希碼
16 int indexOf(int ch)
返回此字符串指定字符第一次出現處的索引
17 int indexOf(int ch, int fromIndex)
返回此字符串指定字符,從指定索引的搜索中第一次出現處的索引
18 int indexOf(String str)
返回此字符串的指定子第一次出現處的索引
19 int indexOf(String str, int fromIndex)
返回此字符串的指定從指定索引處的子字符串第一次出現的索引
20 String intern()
返回字符串對象規範表示形式
21 int lastIndexOf(int ch)
返回此字符串指定字符最後一次出現處的索引
22 int lastIndexOf(int ch, int fromIndex)
返回此字符串指定字符最後一次出現處的索引,從指定索引處開始向後搜索
23 int lastIndexOf(String str)
返回此字符串指定子最右邊出現處的索引
24 int lastIndexOf(String str, int fromIndex)
返回此字符串的指定子最後一次出現處的索引,指定索引處向後開始搜索
25 int length()
返回此字符串的長度
26 boolean matches(String regex)
判斷此字符串是否與給定的正則表達式匹配。
27 boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
檢測兩個字符串區域是不是相等的
28 boolean regionMatches(int toffset, String other, int ooffset, int len)
檢測兩個字符串區域是不是相等的
29 String replace(char oldChar, char newChar)
返回今後字符串中使用newChar替換oldChar全部出現的字符串
30 String replaceAll(String regex, String replacement)
這個替換字符串使用給定的正則表達式匹配並替換每一個子字符串
31 String replaceFirst(String regex, String replacement)
這個替換字符串使用給定的正則表達式匹配替換第一個字符串
32 String[] split(String regex)
圍繞給定的正則表達式的匹配來拆分此字符串
33 String[] split(String regex, int limit)
圍繞給定的正則表達式的匹配來拆分此字符串
34 boolean startsWith(String prefix)
測試此字符串是否以指定的前綴開始
35 boolean startsWith(String prefix, int toffset)
檢測此字符串是否從指定索引開始以指定前綴開始
36 CharSequence subSequence(int beginIndex, int endIndex)
返回一個新的字符序列,它是此序列的子序列
37 String substring(int beginIndex)
返回一個新字符串,它是此字符串的子串
38 String substring(int beginIndex, int endIndex)
返回一個新字符串,它是此字符串的子串
39 char[] toCharArray()
 
這個字符串轉換爲一個新的字符數組
40 String toLowerCase()
 
將全部在這個字符串中的字符的使用默認語言環境的規則轉爲小寫
41 String toLowerCase(Locale locale)
 
將全部在這個字符串中的字符使用給定Locale的規則轉爲小寫
42 String toString()
這個對象(這已是一個字符串!)自己返回。
43 String toUpperCase()
全部的字符在這個字符串使用默認語言環境的規則轉換爲大寫。
44 String toUpperCase(Locale locale)
全部的字符在這個字符串使用給定的Locale規則轉換爲大寫
45 String trim()
返回字符串的副本,開頭和結尾的空白省略
46 static String valueOf(primitive data type x)
返回傳遞的數據類型參數的字符串表示

3.3.1- length()

  • LengthDemo.java
package com.yiibai.tutorial.str;

public class LengthDemo {

    public static void main(String[] args) {
        String str = "This is text";
        int len = str.length();
        System.out.println("String Length is : " + len);
    }
}
運行示例的結果:

3.3.2- concat(String)

  • ConcatDemo.java
package com.yiibai.tutorial.str;

public class ConcatDemo {

    public static void main(String[] args) {
        String s1 = "One";
        String s2 = "Two";
        String s3 = "Three";

        // s1.concat(s2) same as s1 + s2
        String s = s1.concat(s2);
        System.out.println("s1.concat(s2) = " + s);

        // s1.concat(s2).concat(s3) same as s1 + s2 + s3;
        s = s1.concat(s2).concat(s3);

        System.out.println("s1.concat(s2).concat(s3) = " + s);
    }
}
運行示例的結果:
s1.concat(s2) = OneTwo
s1.concat(s2).concat(s3) = OneTwoThree

3.3.3- indexOf(..)

  • IndexOfDemo.java
package com.yiibai.tutorial.str;

public class IndexOfDemo {

    public static void main(String[] args) {
        String str = "This is text";
       
        // Find index within this string of the first occurrence 'i'.
        // ==> 2
        int idx = str.indexOf('i');
        System.out.println("- indexOf('i') = " + idx);

      
        // Find index within this string of the first occurrence 'i'
        // starting the search at index 4.  
        // ==> 5
        idx = str.indexOf('i', 4);
        System.out.println("- indexOf('i',4) = " + idx);
       
        // index within this string of the first occurrence of "te".
        // ==> 8
        idx = str.indexOf("te");
        System.out.println("- indexOf('te') = " + idx);
    }

}
運行示例的結果:
- indexOf('i') = 2
- indexOf('i',4) = 5
- indexOf('te') = 8

3.3.4- substring(..)

  • SubstringDemo.java
package com.yiibai.tutorial.str;

public class SubstringDemo {

    public static void main(String[] args) {
        String str = "This is text";

        // Returns the substring from index 3 to the end of string.
        String substr = str.substring(3);

        System.out.println("- substring(3)=" + substr);

        // Returns the substring from index 2 to index 7.
        substr = str.substring(2, 7);

        System.out.println("- substring(2, 7) =" + substr);
    }
}
運行示例的結果:
- substring(3)=s is text
- substring(2, 7) =is is

3.3.5- replace

與更換的一些方法。
// Returns a new string resulting from replacing all occurrences of
// oldChar in this string with newChar.
public String replace(char oldChar, char newChar)

// Replaces each substring of this string that matches the given  
// 'regular expression' with the given replacement.
public String replaceAll(String regex, String replacement)

// Replaces the first substring of this string that matches
// the given <'regular expression' with the given replacement.
public String replaceFirst(String regex, String replacement)
  • ReplaceDemo.java
package com.yiibai.tutorial.str;

public class ReplaceDemo {

    public static void main(String[] args) {
        String str = "This is text";

        // Replace the character 'i' by 'x'.
        String s2 = str.replace('i', 'x');

        System.out.println("- s2=" + s2);

        // Replace all the strings match "is" by "abc". (Regular Expression)
        String s3 = str.replaceAll("is", "abc");

        System.out.println("- s3=" + s3);

        // Replaces the first substring of this string that matches "is" by "abc".
        String s4 = str.replaceFirst("is", "abc");

        System.out.println("- s4=" + s4);
       
        // (See also document the regular expression)
        // Replace all substring matching expression:
        // "is|te": means "is" or "te" replaced by "+".
        String s5 = str.replaceAll("is|te", "+");
        System.out.println("- s5=" + s5);
    }

}
運行示例的結果:
- s2=Thxs xs text
- s3=Thabc abc text
- s4=Thabc is text
- s5=Th+ + +xt

3.3.6- 其它示例

  • StringOtherDemo.java
package com.yiibai.tutorial.str;

public class StringOtherDemo {

    public static void main(String[] args) {
        String str = "This is text";

        System.out.println("- str=" + str);

        // Return lower case string.
        String s2 = str.toLowerCase();

        System.out.println("- s2=" + s2);

        // Return upper case string
        String s3 = str.toUpperCase();

        System.out.println("- s3=" + s3);

        // Check string started by "This" or not.
        boolean swith = str.startsWith("This");

        System.out.println("- 'str' startsWith This ? " + swith);
       
        // A string with whitespace in beginning and end.
        // Note: \t is tab character
        // \n is new line character
        str = " \t Java is hot!  \t \n ";

        System.out.println("- str=" + str);

        // Returns a copy of the string, with leading and trailing whitespace omitted.
        String s4 = str.trim();

        System.out.println("- s4=" + s4);
    }

}
運行示例的結果:
- str=This is text
- s2=this is text
- s3=THIS IS TEXT
- 'str' startsWith This ? true
- str= 	 Java is hot!  	 
 
- s4=Java is hot!

4- StringBuffer vs StringBuilder

StringBuffer是可變的。它能夠在長度和內容方面發生變化。StringBuffer是線程安全的,這意味着它們已經同步方法來控制訪問,以便只有一個線程能夠在同一時間訪問一個StringBuffer對象同步代碼。所以,StringBuffer的對象一般在多線程環境中是安全的,使用多個線程能夠試圖同時訪問相同StringBuffer對象。html

StringBuilder類很是類似的StringBuffer,不一樣之處在於它的訪問不一樣步的,所以,它不是線程安全的。因爲不一樣步,StringBuilder的性能能夠比StringBuffer更好。所以,若是在單線程環境中工做,使用StringBuilder,而不是StringBuffer可能會有更高的性能。這也相似其餘狀況,如StringBuilder的局部變量(即一個方法中的一個變量),其中只有一個線程會訪問一個StringBuilder對象。java

StringBuffer的方法(StringBuilder類似)
// Constructors
StringBuffer()             // an initially-empty StringBuffer
StringBuffer(int size)     // with the specified initial size
StringBuffer(String s)     // with the specified initial content

// Length
int length()

// Methods for building up the content
// type could be primitives, char[], String, StringBuffer, etc
StringBuffer append(type arg)  // ==> note above!
StringBuffer insert(int offset, type arg) // ==> note above!

// Methods for manipulating the content
StringBuffer delete(int start, int end)
StringBuffer deleteCharAt(int index)
void setLength(int newSize)
void setCharAt(int index, char newChar)
StringBuffer replace(int start, int end, String s)
StringBuffer reverse()

// Methods for extracting whole/part of the content
char charAt(int index)
String substring(int start)
String substring(int start, int end)
String toString()

// Methods for searching
int indexOf(String searchKey)
int indexOf(String searchKey, int fromIndex)
int lastIndexOf(String searchKey)
int lastIndexOf(String searchKey, int fromIndex)

  • StringBuilderDemo.java
package com.yiibai.tutorial.strbb;


public class StringBuilderDemo {

    public static void main(String[] args) {
       
        // Create StringBuilder object
        // with no characters in it and
        // an initial capacity specified by the capacity argument
        StringBuilder sb = new StringBuilder(10);
        
        // Append the string Hello ... on sb.
        sb.append("Hello...");
        System.out.println("- sb after appends a string: " + sb);

        // append a character
        char c = '!';
        sb.append(c);
        System.out.println("- sb after appending a char: " + sb);

        // Insert a string at index 5
        sb.insert(8, " Java");
        System.out.println("- sb after insert string: " + sb);
        
    
        // Delete substring at index 5 to 8
        sb.delete(5,8);

        System.out.println("- sb after delete: " + sb);
    }
}
運行示例的結果:
- sb after appends a string: Hello...
- sb after appending a char: Hello...!
- sb after insert string: Hello... Java!
- sb after delete: Hello Java!
相關文章
相關標籤/搜索