String 、 StringBuffer 和 StringBuilder 类
字符串就是一连串的字符序 列, Java 提供 了 String 、 StringBuffer 和 StringBuilder 三个类来封装宇符串,并提供了 一系列方法来操作字符串对象 。
- String 类是不可变类 ,即 一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的 , 直至这个对象被销毁。
- StringBuffer 对 象 则代 表一个字符序列可变的 字符串 ,当 一个 StringBuffer 被创建以后,通过StringBuffer 提供的 append() 、 insert() 、 reverse() 、 setCharAt() 、 setLength()等方法可以改变这个字符串对象的宇符序列。一旦通过 StringBuffer 生成了 最终想要的字符串,就可以调用它的 toStringO方法将其转换为一个 String 对象 。
- StringBuilder 类是 JDK 1.5 新增的类 ,它也代表可变宇符串对象 。 实际上, StringBuilder 和 StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是 , StringBuffer 是线程安全的,而 StringBuilder则没有实现线程安全功能 ,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象, 则应该优先考虑使用 StringBuilder 类。
String类
String类提供了大量构造器来创建String对象,其中如下几个有特殊用途:
- String():创建一个包含0个字符串序列的String对象(并不是返回null)。
- String(byte[] bytes,Charset charset):使用指定的字符集将指定的byte[擞组解码成一个新的String 对象。
- String(byte[] bytes,int offset,int length):使用平台的默认字符集将指定byte[]数组从ofifeet开始、长度为length的子数组解码成一个新的String对象。
- String(byte[] bytes,int length,String charsetName):使用指定的字符集将指定的 byte[]数 组从offset开始、长度为length的子数组解码成一个新的String对象。
- String(byte[] bytes,String charsetName):使用指定的字符集将指定的byte[]数组解码成一个新的 String 对象。
- String(char[] value,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 指 的是字符串的序数,字符串的序数从 0 开始到 length()-l 。 如下代码所示:
String s = new String("fkit.org");
System .out. println("s.charAt(5): "+ s.charAt(5) );
结果为:
s . charAt(5) : 0
- int compareTo(String anotherString): 比较两个宇符串的大小 。 如果两个字符串的字符序列相等,则返回 0; 不相等时,从两个字符串第 0 个字符开始比较,返回第一个不相等的字符差。另一种情况,较长字符串的前面部分恰巧是较短的字符串,则返回它们的长度差。
String s1 = new String( "abcdefghijklmn");
String s2 = new String( "abcdefghij ");
String s3 = new String( "abcdefghijalmn") ;
System.out .println( "sl. compareTo(s2) : " + sl. compareTo(s2) ) ; //返回长度差
System.out.println( "sl. compareTo (s3): " + sl. compareTo(s3) ) ; //返回 'k'-'a' 的差
结果为 :
s1.compareTo(s2): 4
s1.compareTo(s3) : 10
- String concat(String s):将该 String 对象与调用对象连接在一起。与 Java 提供的字符串连接运算符" +"的功能相同。
- boolean contentEquals(StringBuffer sb): 将该 String 对象与 StringBuffer 对象 sb 进行比较,当它们包含的字符序列相同时返回 true 。
- static String copyValueOf(char[] data): 将字符数组连缀成字符串,与 String(char[] content)构造器的功能相同 。
- static String copyValueOf(char[] data,int count): 将 char 数组的子数组中的元素连缀成字符串,与 String(char[] value,int count)构造器的功能相同 。
- boolean endsWith(String suffix): 返回该 String 对象是否以 suffix 结尾 。
String s1 = "fkit. org"; String s2 = ". org";
System.out .println("s1 .endsWith(s2): " + s1.endsWith(s2) );
结果为:
s1 .endsWith(s2): true
- boolean equals(Object anObject): 将该字符串与指定对象比较,如果二者包含的字符序列相等,则返回 true; 否则返回 false 。
- boolean equalsIgnoreCase(String s):与前 一个方法基本相似,只是忽略字符的大小写 。
- byte[] getBytes(): 将 该 String 对象转换成 byte 数组 。
- void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin): 该方法将字符串中从 srcBegin 开始,到 srcEnd 结束的字符复制到 dst 字符数组中,其中 dstBegin 为目标字符数组的起始复制位置。
char[] s1 = {'I',' ',' l',' o',' v',' e ','j',' a',' v ',' a'); // s1=1 love_java
String s2 = new String( "ejb");
s2 .getChars(0,3,s1,7); // s1=I love java
System.out . println ( s1 );
结果为:
I love java
- int indexOf(int ch): 找出 ch 字符在该字符串中第一次 出现的位置 。
- int indexOf(int ch,int fromIndex): 找出 ch 字符在该字符串中从企fromIndex 开始后第一 次出现的位置。
- int indexOf(String s):找出 str 子字符串在该宇符串中第 一次出现的位置 。
- int indexOf(String s, int fromIndex): 找出 s位子字符串在该字符串中从 fromIndex 开始后第一次出现的位置。
String s = "www.fkit .org"; String ss = "it ";
System. out .print1n( "s.indexOf( ' r ' ): " + s .indexOf( ' r ') );
System .out.print1n( "s . indexOf( ' r ',2) : " + s.indexOf('r ',2) );
System.out.print1n( " s . indexOf(ss): " + s.indexOf(ss)) ;
结果为:
s .indexOf( 'r'): 10
s . indexOf (' r ',2) : 10
s . indexOf (ss) : 6
- int lastIndexOf(int ch): 找出 ch 字符在该字符串中最后一次出现的位置。
- int lastIndexOf(int ch,int fromIndex): 找出 ch 字符在该字符串 中从 fromIndex 开始后最后一次出现的位置 。
- int lastIndexOf(String str):找出 str子字符串在该字符串中最后 一次 出现的位置 。
- int lastIndexOf(String str, int fromIndex): 找出 str 子字符串在该字符串中从 台fromlndex 开始后最后一次出现的位置 。
- int length(): 返回当前字符串长度。
- String replace(char oldChar,char newChar): 将字符串中的第一个 oldChar 替换成 newChar 。
- boolean startsWith(String prefix): 该 String 对象是否以 prefix 开始。
- boolean startsWith(String prefix , int toffset): 该 String 对象从 toffset 位置算起,是否以 prefix 开始。
String s = "www . fki t .org"; String ss = "www"; String sss = "fkit ";
System.out .print1n("s.startsWith (ss): " + s.startsWith(ss) );
System.out .print1n( "s.startsWith(sss,4): " + s.startsWith (sss,4));
结果为 :
s .startsWith(ss) : true
s.startsWith(sss,4): true
- String substring(int beginlndex): 获取从 beginlndex 位置开始到结束的子字符串。
- String substring(int beginlndex,int endIndex): 获取从 beginIndex 位置开始到 endlndex 位置的子字符串。
- char[] tocharArray(): 将该 String 对象转换成 char 数组。
- String toLowerCase(): 将字符串转换成小写。
- String toUpperCase(): 将字符串转换成大写。
String s = "fkjava.org ";
System.out.print1n( "s.toUpperCase() : " + s . toUpperCase()) ;
System.out.print1n( "s.toLowerCase(): " + s.toLowerCase()) ;
结果为 :
s . toUpperCase() : FKJAVA .ORG
s.toLowerCase() : fkjava .org
- static String valueOf(X x): 一系列用于将基本类型值转换为 String 对象的方法 。
String 类是不可变的, String类的实例一旦生成就不会再改变了。
例如如下代码:
String str1 = "java";
str1 = str1 + "struts ";
str1 = str1 + " spring";
上面程序除使用了 3 个字符串直接量之外,还会额外生成 2 个字符串直接量一一 "java"和 "struts"连接生成的 "javastruts" , 接着 "javastruts"与 "spring"连接生成 的 "javastrutsspring" , 程序中 的 strl 依次指向 3个不同的字符串对象。
字符串存储
对于不同版本的JDK,String类在内存中有不同的优化方式。具体来说,早期JDK版本的String总是以char[]存储,它的定义如下:
public final class String {
private final char[] value;
private final int offset;
private final int count;
}
而较新的JDK版本的String则以byte[]存储:如果String仅包含ASCII字符,则每个byte存储一个字符,否则,每两个byte存储一个字符,这样做的目的是为了节省内存,因为大量的长度较短的String通常仅包含ASCII字符:
public final class String {
private final byte[] value;
private final byte coder; // 0 = LATIN1,1 = UTF16
}
API:java.lang.String
StringBuilder、StringBuffer
为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
StringBuilder 提供了一系列插入、追加、改变该字符串里包含 的 字符序 列的方法 。 而 StringBuffer与其用法完全相同,只是 StringBuffer 是线程安全 的 。
StringBuilder 、 StringBuffer 有两个属性 : length 和 capacity , 其中 length 属性表示其包含的字符序列的长度。与 String 对象的 length 不同的 是:StringBuilder、 StringBuffer 的 length 是可以改变的,可以通过 length()、 setLength(int len)方法来访 问和修改其字符序列的长度。 capacity 属性表示 StringBuilder的容量, capacity 通常比 length 大,程序通常无须关心 capacity 属性。 如下程序示范了 StringBuilder 类的用法: