String、StringBuffer和StringBuilder类

字符串是一连串的字符序列,Java提供了String和StringBuffer两个类来封装字符串,并提供了系列方法来操作字符串
String类是不可变类,即一旦一个String对象呗创建以后,包含在这个对象的字符串序列是不可改变的,直至这个对象
销毁。
StringBuffer对象则代表一个字符串序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的
append、insert、reverse、setCharAt、setLength等方法可以改变这个字符串序列对象的字符串序列。一旦通过StringBuffer
生成了最终想要的字符串,就可以调用它的toString方法将其转换为一个String对象。
JDK1.5又新增了一个StringBuilder类,它代表了字符串对象。实际上,StringBuilder和StringBuffer基本类似,两个
类的构造器和方法也基本相同。不同的是,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以
性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,应该优先考虑使用StringBuilder类。 
String类提供了大量构造器来创建String对象,其中如下几个有特殊用途:
== String():创建一个包含0个字符串序列的String对象(并不是返回null)。
== String(byte[]bytes,Charset charset):使用指定的字符集将指定的byte数组解码成一个新的String对象。
== String(byte[]bytes,int offset,int length):使用平台的默认字符集将指定的byte数组的offset开始鼓、长度
为length的子数组解码成一个新的String对象。
== String(byte[]bytes,int offset,int length,String charsetName):使用指定的字符集将指定byte数组的offset
开始、长度为length的子数组解码成一个新的String对象。
== String(byte[]bytes,String charsetName):使用指定的字符集将指定的byte数组解码成一个新的String对象。
== String(char[]values,int offset,int count):将指定字符串数组从offset开始、长度为count的字数组中的字符元素
连缀 成字符串。
== String(String original):根据字符串直接量来创建一个String对象。也就是说,新创建的String对象时该参数
字符串的副本。
== String(StringBuffer buffer):根据StringBuffer对象来创建对应的String对象。
== String(StringBuilder builder):根据StringBuilder对象来创建对应的String对象。
== String类也提供了大量方法来操作字符串对象,下面详细介绍这些常用方法:
== char charAt(int index):取字符串中的指定位置的字符,其中,参数index指的是字符串序数。如下代码:
String s = new String("abcdefghijklmn");
System.out.println("s.charAt(5):" + s.charAt(5));
结果为:
s.charAt(5):5
== int compareTo(String anotherString):拿当前String对象与anotherString对象比较。如果两个字符串的字符
序列相等则返回0;不相等时,从两个字符串第0个字符开始比较,返回第一个不相等的字符差,另一种情况,较长字符串的
前面部分恰巧是较短的字符串,返回它们的长度差
== 后面关于String的方法还有很多,详细了解可以查询api。


String类是不可改变的,String实例一旦生成就不会再改变了,例如如下代码:
String str = "java" + "struts" + "spring";
上面程序除了使用4个字符串直接常量之外,还会额外生成2个字符串常量,其中“java”和“struts”生成了“javastruts”
保存在内存中,接着“javastruts”与“spring”生成“javastrutsspring”字符串,并将它赋给str变量。因为String是不可变
的,所以会额外产生很多的临时变量,使用StringBuffer或StringBuilder就可以避免这个问题。
常量池指的是在编译期被确定、并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量

,也包含字符串常量。看如下程序:

[java]  view plain copy
  1. String s0 = "hello";  
  2. String s1 = "hello";          
  3. String s2 = "he" + "llo";  
  4. System.out.println(s0 == s1);  
  5. System.out.println(s0 == s2);  
  6. System.out.println(new String("hello") == new String("hello"));  
运行结果为:
true
true
false
长须最后一行输出false比较好理解:因为两次new出的String对象不是同一个对象,所以使用==比较返回false.
Java会确保每个字符串常量只有一个,不会产生很多副本。本例子中的s0和s1中的“hello”都是字符串常量,他们在编译
期就被确定了,所以s0==s1返回true;而“he”和“llo”也都是字符串常量,当一个字符串常量由多个字符串常量连接而成时,
它本身就是字符串常量,所以s2同样在编译期就被解析成一个字符串常量,所以S2也是常量池中“hello”的引用。
用 new String()创建的字符串不是常量,不能在编译期就确定,所以new String()创建的字符串不会放在常量池中,他们
有自己的地址空间。 
StringBuilder、StringBuffer则提供了系类插入、追加、改变该字符串里包含的字符串序列。而StringBuffer与其用法
完全相同,只是StringBuilder是线程安全的。
StringBuilder、StringBuffer有两个属性:length和capacity,其中length属性代表了其包含的字符串序列长度,与String
对象的length不同的是,StringBuilder、StringBuffer的length是可以改变的,可以通过length()和setLength(int len)方法
里访问和修改其字符串序列的长度。capacity属性代表了StringBuilder的容量,capacity通常比length大,程序通常不
关心capacity的属性。

[java]  view plain copy
  1. public class TestStringBuilder {  
  2.     public static void main(String[] args) {  
  3.         StringBuilder sb = new StringBuilder();  
  4.         //追加字符  
  5.         sb.append("java");//sb="java";  
  6.         //插入  
  7.         sb.insert(0"hello ");//sb="hello java";  
  8.         //替换  
  9.         sb.replace(56",");//sb="hello,java";  
  10.         //删除  
  11.         sb.delete(56);//sb="hellojava";  
  12.         System.out.println(sb.toString());  
  13.           
  14.         //反转  
  15.         sb.reverse();//sb="avajolleh";  
  16.           
  17.           
  18.         System.out.println(sb.toString());  
  19.         System.out.println(sb.length());//输出9  
  20.         System.out.println(sb.capacity());//输出16  
  21.         //改变StringBuilder的长度,将只保留前面部分  
  22.         sb.setLength(5);//sb="avajo";  
  23.         System.out.println(sb.toString());  
  24.     }  
  25. }  

你可能感兴趣的:(与运行环境交互)