String类中每一个看起来会修改String值得方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象则丝毫未动。 —《Java编程思想》第13章
0X00 String常量池 如果使用常用的方式定义两个内容完全一样的字符串,那么Java使用常量的方式,也就是说第二个字符串并没有生成一个对象而是引用了之前的字符串,导致他们的本质是一样的,所以当使用==
判断两个字符串对象是否是同一个对象的时候,会显示是同一个对象。但是如果我们每次声明一个字符串的时候使用new String()
的方式,则会每次创建一个String对象,两者就不是同一个对象了。
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Main { public static void main (String args[]) { String str1 = "hello,world" ; String str2 = "hello,world" ; System.out.println(str1 == str2); String str3 = new String("hello,world" ); String str4 = new String("hello,world" ); System.out.println(str3 == str4); } }
0X01 StringBuilder 字符串的拼接在Java中非常方便,但常用的使用+
来拼接字符串效率很低,在需要拼接的次数不是很多的时候不会影响多少效率,但当需要拼接的字符串数量很多的时候就需要使用StringBuilder
来拼接。该类中有一个append()
的方法,就是将一个字符串连接到本对象的字符串后面。下面我们来对比一下这两个拼接方法的速度差异。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Main { public static void main (String args[]) { String string = "hello,world" ; long start = new Date().getTime(); for (int i = 0 ; i < 10000 ; i++){ string += "hello,world" ; } long middle = new Date().getTime(); StringBuilder stringBuilder = new StringBuilder("hello,world" ); for (int i = 0 ; i < 10000000 ; i++){ stringBuilder.append("hello,world" ); } long end = new Date().getTime(); System.out.println("使用+连接耗时: " + (middle - start)); System.out.println("使用StringBuilder连接耗时: " + (end - middle)); } }
执行结果如下
1 2 使用+连接耗时: 850 使用StringBuilder连接耗时: 263
速度差异很明显,使用加号连接只连接一万次就耗时800多毫秒,而使用StringBuilder即使连接一千万次也只需要200多毫秒。
该类中还有其他的方法insert()指定位置插入
/ replace()分片赋值
/ substring()提取子字符串
/ reverse()翻转字符串
/ toString()返回字符串
使用演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Main { public static void main (String args[]) { StringBuilder stringBuilder = new StringBuilder("0123456789" ); stringBuilder.insert(5 , "hello,world" ); System.out.println(stringBuilder.toString()); stringBuilder = new StringBuilder("0123456789" ); stringBuilder.replace(3 , 5 , "hello,world" ); System.out.println(stringBuilder.toString()); stringBuilder = new StringBuilder("0123456789" ); stringBuilder.substring(3 , 5 ); System.out.println(stringBuilder.toString()); stringBuilder = new StringBuilder("0123456789" ); stringBuilder.reverse(); System.out.println(stringBuilder.toString()); } }
0X02 String的其他方法 String类中有很多方法,这里有几个常用的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class Main { public static void main (String args[]) { String string; boolean bool; string = "hello,world" ; bool = string.equals("hello,world" ); System.out.println(bool); string = "hello,world" ; bool = string.contains("hello" ); System.out.println(bool); string = "hello,world" ; bool = string.startsWith("he" ); System.out.println(bool); string = "hello,world" ; string = string.replace("world" , "java" ); System.out.println(string); string = "hello,world" ; string = string.toUpperCase(); System.out.println(string); string = " hello,world " ; string = string.trim(); System.out.println(string); } }
0X03 String的正则方法 简单的正则匹配可以直接使用String类中的方法,比如查看字符串是否符合某正则表达式的matches()
和切割字符串的split()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Main { public static void main (String args[]) { String string = "java0python00cpp" ; System.out.println(string.matches("[\\w\\d]+" )); System.out.println(); String[] strings = string.split("\\d+" ); for (int i = 0 ; i < strings.length; i++){ System.out.print(strings[i] + " " ); } } }