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对象。

StringBuilder类非常相似的StringBuffer,不同之处在于它的访问不同步的,因此,它不是线程安全的。由于不同步,StringBuilder的性能可以比StringBuffer更好。因此,如果在单线程环境中工作,使用StringBuilder,而不是StringBuffer可能会有更高的性能。这也类似其他情况,如StringBuilder的局部变量(即一个方法中的一个变量),其中只有一个线程会访问一个StringBuilder对象。

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!

 

 

posted on 2016-08-19 13:00  Java初级码农  阅读(10216)  评论(0编辑  收藏  举报

导航