第十三章 字符串(一)之 String
这一节来学习String的特性和方法。
一、String对象的不变性
不变性:String对象是由一个final char[] value 数组实现的,因此String对象是不可变的。任何看起来改变String对象的行为,其实质就是创建了一个新的对象。
示例一:
public class Demo1 { public static String upcase(String s) { return s.toUpperCase(); } public static void main(String[] args) { // TODO Auto-generated method stub String s1 = "abc"; String s2 = upcase(s1); System.out.println("s1: " + s1); System.out.println("s2: " + s2); } }
输出结果:
s1: abc
s2: ABC
结果说明:可以看到s1所指向的对象没有发生变化,得到的只是一个新的String。
二、String、StringBuilder、StringBuffer
1、区分String、StringBuilder、StringBuffer
这三个类都是继承自CharSequence,他们都是字符序列,只不过类型不同特点不同罢了。
String:底层实现是使用final char[] value数组实现,所以String对象的内容不可更改。
StringBuilder:可以在原序列上进行append和insert等操作,来改变原字符序列的内容,不过它是线程不安全的。
StringBuffer:它和StringBuilter用法一样,但是它是线程安全的,要花费更大的代价,自然就没有StringBuilter快。
2、StringApI
我这里并没有全列出,挑几个熟悉一下就好,也没有必要全部记得。
1 package stringdemo; 2 3 public class Demo2 { 4 5 public static void main(String[] args) { 6 //使用byte数组初始String 7 String s = new String(new byte[] {0x61, 0x62, 0x63, 0x64, 0x65}); 8 System.out.println("[1] s: " + s); 9 //length()返回String的长度 10 System.out.println("[2] length(): " + s.length()); 11 //charAt()返回指定索引处的Char值 12 System.out.println("[3] charAt(): " + s.charAt(0)); 13 //contains()是否包含参数内容 14 System.out.println("[4] contains(): " + s.contains("abc")); 15 //contentEquals()两个String内容全等,则为true 16 System.out.println("[5] contentEquals(): " + s.contentEquals("abcde")); 17 //concat()链接字符串 18 System.out.println("[6] concat(); " + s.concat("fg")); 19 //返回指定数组的String形式 20 System.out.println("[7] copyValueOf(): " + String.copyValueOf(new char[] {'x', 'y', 'z'})); 21 //equalsIgnoreCase()忽略大小写,全等则相等 22 System.out.println("[8] equalsIgnoreCase(): " + s.equalsIgnoreCase("ABCDE")); 23 //endsWith()匹配指定后缀 24 System.out.println("[9] endsWith(): " + s.endsWith("de")); 25 //starsWith()匹配指定前缀 26 System.out.println("[10] startsWith(): " + s.startsWith("ab")); 27 //返回一个代表String内容的char数组 28 char[] chars = new char[10]; 29 s.getChars(0, 5, chars, 0); 30 System.out.print("[11] getChars(): "); 31 for(char c : chars) { 32 System.out.print(c + " "); 33 } 34 System.out.println(); 35 //返回一个代表String内容的byte数组 36 byte[] bytes = s.getBytes(); 37 System.out.print("[12] getBytes(): "); 38 for(byte b : bytes ) { 39 System.out.print(b + " "); 40 } 41 42 System.out.println(); 43 44 //换回指定字母在String序列中的下标 45 System.out.println("[13] indexOf(): " + s.indexOf('c')); 46 //String与正则表达式是否相匹配 47 System.out.println("[14] matches(): " + s.matches("[a-f]+")); 48 //返回String的子串 49 System.out.println("[15] substring():" + s.substring(1,3)); 50 //返回数组的String形式 51 System.out.println("[16] valueOf(): " + String.valueOf(new char[] {'u', 'v', 'w'})); 52 53 54 } 55 56 }
输出结果:
[1] s: abcde
[2] length(): 5
[3] charAt(): a
[4] contains(): true
[5] contentEquals(): true
[6] concat(); abcdefg
[7] copyValueOf(): xyz
[8] equalsIgnoreCase(): true
[9] endsWith(): true
[10] startsWith(): true
[11] getChars(): a b c d e
3、在循环中使用StringBuilder更加高效
1 public class Demo4 { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 StringBuilder s = new StringBuilder("["); 6 for(int i = 0; i < 10; i++) { 7 s.append(i); 8 s.append(", "); 9 } 10 s.delete(s.length()-2, s.length()); 11 s.append("]"); 12 System.out.println(s); 13 } 14 15 }
输出结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
结果说明:对String的链接操作编译器都会生成StringBuilder对象,因为StringBuilder更加高效,在循环中使用StringBuilder对象,编译器就只会生成一个StringBuilder对象,如若使用String,则编译器会生成很多StringBuilder对象。