Java-String字符串相关
字符串String:
封装char[] 字符数组,不可变(因为在底层代码中,值用final关键字修饰)
字符串的字面值:
如果第一次用到一个字符串字面值,会在内存中“字符串常量池”内新建对象,当再次使用相同字面值时,
直接访问常量池中存在的实例,而不新建对象。
1 public class TestString { 2 3 public static void main(String[] args) { 4 char[] a = {'h','e','l','l','o'}; 5 String s1 = new String(a); //内存中新分配内存空间 6 String s2 = "hello"; //在常量池新建对象 7 String s3 = "hello"; //访问常量池存在的对象 8 9 System.out.println(s1); 10 System.out.println(s2); 11 System.out.println(s3); 12 13 System.out.println(s1 == s2); //输出false,内存地址不相等 14 System.out.println(s2 == s3); //输出true,内存地址相等,引用指向同一个对象 15 16 System.out.println(s1.equals(s2)); //比较字符内容 17 } 18 }
字符串连接效率:
字符串一旦创建,字符串的内容不可变,任何对字符串修改的操作,都是在新建字符串。
接下来采用System.currentTimeMillis()方法来观察用String拼接字符串的效率。先在拼接行为前记录当前时间,再在拼接行为后也记录一下时间,相减后即为拼接行为所花的时间。
1 public class Test01 { 2 3 public static void main(String[] args) { 4 String s0 = "abcdefqhijklmnopqrstuvwxyz"; 5 String s = ""; 6 //系统当前时间点毫秒值 7 //毫秒值:1970-1-1 0点开始的毫秒值 8 long t = System.currentTimeMillis(); 9 for(int i=0;i<100000;i++) { 10 s += s0; 11 } 12 t = System.currentTimeMillis() - t; 13 System.out.println(t); 14 } 15 }
输出结果为140285,拼接行为花了140285毫秒,共创建100000个对象,显然效率很低,而且十分浪费空间。
高效率字符串连接:
StringBuilder、StringBuffer:
封装char[]字符数组,可变。(值没有用final修饰)
StringBuilder和StringBuffer的区别:
StringBuilder 线程不安全,效率高;StringBuffer 线程安全,效率低。通常都是用StringBuilder
采用StringBuilder进行字符串连接,通过在原字符数组基础上的数组扩容进行拼接,不会建立新对象,可以显著提高连接效率。
依旧采用System.currentTimeMillis()方法来观察用StringBuilder拼接字符串的效率。
1 public class Test02 { 2 3 public static void main(String[] args) { 4 String s0 = "abcdefqhijklmnopqrstuvwxyz"; 5 StringBuilder sb = new StringBuilder(""); 6 //系统当前时间点毫秒值 7 //毫秒值:1970-1-1 0点开始的毫秒值 8 long t = System.currentTimeMillis(); 9 for(int i=0;i<100000;i++) { 10 sb.append(s0); 11 } 12 t = System.currentTimeMillis() - t; 13 System.out.println(t); 14 } 15 }
输出结果为11,拼接行为只花了11毫秒,显然效率提高了很多很多。