一、关于String
String类生成对象有三种方法,第一种是new一个String类的新对象,第二种是直接输入一个字符串,第三种为String类提供的静态方法String.valueOf()进行类型转换。如下所示:
String str1 = new String("abcde");
System.out.println(str1);
String str2 = "aBcd";
System.out.println(str2);
//第三种生成方法,字符转换
String str3 = String.valueOf(5201314);
System.out.println(str3);
在Java 中使用字符串最重要的一个规则必须记住,一个字符串对象一旦被创建,它的内容就是固定不变的 public static String str = "abc";这个声明会创建一个长度为3,内容为abc的字符串对象,您无法改变这个字符串对象的内容。虽然可以使用str = "1111";来使输出str为1111。但是不要以为这样就改变了字符串对象的内容。
事实上。上面那段代码中产生了两个字符串对象,一个是abc字符串对象,长度为3;一个是1111字符串对象,长度为4,两个不同的字符串对象。不是在abc 字符串改为1111字符串,而是让str 引用名称从新引用1111字符串,而不在引用abc 字符串但abc字符串在内存中还是存在的,只是现在没有被引用。所以输出1111。
在String类中也提供了很多方法,下面简单介绍几个比较常用的。
System.out.println(str1.equals(str4));//equals在String类中已经覆盖过了,故不是比较首地址
System.out.println(str2.equalsIgnoreCase(str4));//不区分大小写相等比较
System.out.println("str1 == str2 :" + (str1 == str2));
System.out.println("str4 == str2 :" + (str4 == str2));//首地址比较
System.out.println(str3.length());
System.out.println(str3.substring(0, 0+4));//substring(m, m+n)截取从m开始的n位
System.out.println(str3.substring(1, 1+4));
System.out.println(str3.substring(1));//substring(m),从m起到全部
System.out.println(str3);//同replace,未改变本质,再次输出时依旧为原始值
System.out.println(str3 + 521);
str3 = new String("我爱我中华 !");
System.out.println(str3);
System.out.println(str3.replace("我", "我们"));//指定替换replace("m", "n"),n换m,替换的并不是实例的本质,所以再次输出时依旧是未替换之前的
str3.replace("我", "我们");
System.out.println(str3);
由上图所示:
1、相等比较方法
引用方式为“对象.equals(对象)”,这个方法可以比较字符串,但是会区分大小写 ,大小写必须一致才输出true。如果想不用区分大小写的话可以引用equalslgnoreCase方法。测试如下:
System.out.println(str1.equals(str4));//equals在String类中已经覆盖过了,故不是比较首地址
System.out.println(str2.equalsIgnoreCase(str4));//不区分大小写相等比较
System.out.println("str1 == str2 :" + (str1 == str2));
System.out.println("str4 == str2 :" + (str4 == str2));//首地址比较
结果如下:
直接比较的话是比较两个对象首地址,即使指向的值相同也会输出false。
2、字符串截取特定部分
substring(m, m+n)的含义是截取从m开始的n位,且字符串中下标从0开始。例:str3.substring(0, 0+4)代表截取str3的第一个字符到第四个字符。substring(m)的含义是从m起到最后一个字符。测试如下:
System.out.println(str3.substring(0, 0+4));//substring(m, m+n)截取从m开始的n位
System.out.println(str3.substring(1, 1+4));
System.out.println(str3.substring(1));//substring(m),从m起到全部
System.out.println(str3);//同replace,未改变本质,再次输出时依旧为原始值
结果如下:
这个测试也验证了一个字符串对象一旦被创建,它的内容就是固定不变的 !不管引用其他的任何方法都无法改变这个事实。
3、指定替换
指定替换replace("m", "n"),n换m,替换的并不是实例的本质,所以再次输出时依旧是未替换之前的,即同样验证了一个字符串对象一旦被创建,它的内容就是固定不变的 !测试如下:
System.out.println(str3.replace("我", "我们"));//指定替换replace("m", "n"),n换m,替换的并不是实例的本质,所以再次输出时依旧是未替换之前的
str3.replace("我", "我们");
System.out.println(str3);
二、关于StringBuffer 和 StringBuilder
由于一个字符串对象一旦被创建,它的内容不再改变的原因,当需要对一个字符串进行频繁改变值时就会耗费大量时间,故我们可以使用StringBuffer 或 StringBuilder。二者的区别仅仅在于StringBuffer线程安全,StringBuilder线程不安全。故我们着重介绍StringBuffer。
StringBuffer类的生成方法只有一种,只能new一个新对象。StringBuffer类也同样提供了replace方法,replace(m, m+n, "xxxx"),用xxxx 替换从m个开始的n位。
StringBuffer str1 = new StringBuffer("abcdef");
str1.replace(2, 2+3, "wzry");//replace(m, m+n, "xxxx"),用xxxx 替换从m个开始的n位
System.out.println(str1);
StringBuffer类提供了一个与String不同的append方法,这个方法可以添加字符进入字符串。
为了展示出StringBuffer与String在多次改变值的消耗时间对比,测试分别改变10000次数值所消耗的时间。 测试如下:
int count = 10000;
long startTime = System.currentTimeMillis();
StringBuffer strbuf = new StringBuffer();
for(int i = 1; i < count; i++) {
strbuf.append(i);//StringBuffer提供的专有添加方法
}
long endTime = System.currentTimeMillis() - startTime;
System.out.println("耗时:" + endTime / 1000 + "." + String.valueOf(endTime % 1000 + 1000).substring(1) + "秒");
startTime = System.currentTimeMillis();
String str = new String(" ");
System.out.println(str);
for(int i = 1; i < count; i++) {
str += i;//这里太低效了,因为每次等于并不是改变str的值,而是new一个新对象,故耗时很多,换用StringBuffer或StringBuilder,二者无本质差别,近似于相等
}
endTime = System.currentTimeMillis() - startTime;
System.out.println("耗时:" + endTime / 1000 + "." + String.valueOf(endTime % 1000 + 1000).substring(1) + "秒");
StringBuffer strB = new StringBuffer();
strB.append(12457);
System.out.println(strB);
}
结果如下:
使用StringBuffer速度比String快了200多倍。故在字符串频繁改动时使用StringBuffer速度更快更高效。