String、StringBuilder和StringBuffer
- String隶属于java.lang包下的类,具体方法参见java的ApI
public static void main(String[] args) {
System.out.println(String.class);
}
输出结果为:class java.lang.String
- String是引用类型,不属于八大类型,因而,我们要格外注意String的用法。String如果是字符串直接相加,在java的编译期间就已经被优化了,比如String str=“hello”+“java”,在java编译期间,会被优化成“hellojava”;
public static void main(String[] args) {
String str1="hellojava";
String str2="hello"+"java";
String str3="hello";
String str4="java";
String str5=str3+str4;
String str6=str3+"java";
String str7=str5.intern();
System.out.println("str1=str2?:"+(str1==str2)); //语句1
System.out.println("str1=str5?:"+(str1==str5)); //语句2
System.out.println("str1=str6?:"+(str1==str6)); //语句3
System.out.println("str2=str5?:"+(str2==str5)); //语句4
System.out.println("str2=str6?:"+(str2==str6)); //语句5
System.out.println("str5=str6?:"+(str5==str6)); //语句6
System.out.println("str1=str7?:"+(str1==str7)); //语句7
你会发现,只有语句1和语句7位true,余下的都为FALSE,为什么会这样呢?
- 对于语句1来说,String str2=”hello”+”java”;java虚拟机在编译期间,已经将其优化成“hellojava”,它存在于栈中的一块内存,str1和str2同时指向这块内存,因而,他们引用对象的值是相等的,也就是,他们指向“hellojava”首地址是相等。
- str5和str6在java编译期间是无法被优化,因而,他们引用的对象是不相等。
-
对于语句7来说,如果,在内存中存在str5这个对象,会返回该对象的引用,因而,语句1和语句7是相等的,他们指向的值是相等。
3.String StringBuilder StringBuffer
StringBuilder和StringBuffer用法差不多,只不过后者是线程安全的,方法的前面用synchronized来修饰。它们执行的效率如下
package mytest;
public class TestString {
public static void main(String[] args) {
String str = "hello world";
String str1="你好世界";
String str2="java";
StringBuilder sBuilder = new StringBuilder("helle world");
StringBuffer sBuffer = new StringBuffer("hello world");
/**
* 这种操作的执行时间为:
* String对象“+=”操作,执行20万次的时间为:38秒
* 为什么会有需要这么长的时间,因为每次执行一次加操作时,内部会自动生成一个String对象
* 也就是说,新生成的对象会重新指向引用对象,因而,一共生成了20万个String对象,如果
* java的gc操作,那么很容易初心oom异常,也就是OutOfMember,内存异常
* 因而,它的执行效率会比较慢
*
*/
long start1 = System.currentTimeMillis();
for (int i = 0; i <= 2E5; i++) {
str += "你好";
}
long end1 = System.currentTimeMillis();
System.out.println("String对象“+=”操作,执行20万次的时间为:" + (end1 - start1)
/ 1000 + "秒\n");
/**
* 这种操作的执行时间为:33毫秒
* jvm不会将其优化,必须在运行时才操作,效率相对较低
*
*
*/
long start2 = System.currentTimeMillis();
for (int i = 0; i <= 2E5; i++) {
str =str1+str2;
}
long end2 = System.currentTimeMillis();
System.out.println("变量加字符串,执行20万次的时间:" + (end2 - start2)+ "毫秒\n");
/**
* 这种操作的执行时间为:3毫秒
* 因为在java虚拟机的编译时期,JVM会将其优化成“你好java世界”,也就是,
* 在编译时期就确定了它的值,因而,效率会最高
*
*/
long start3 = System.currentTimeMillis();
for (int i = 0; i <= 2E5; i++) {
str ="你好"+"java"+"世界";
}
long end3 = System.currentTimeMillis();
System.out.println("字符串直接相加,执行20万次的时间:" + (end3 - start3)
+ "毫秒\n");
/**
* 这种操作的执行时间为:30毫秒
* StringBuilder是值可变的,通过append方法,没有创建新的对象,因而效率很高
* 这是单线程的。
*
*/
long start4 = System.currentTimeMillis();
for (int i = 0; i <= 2E5; i++) {
sBuilder.append(i);
}
long end4 = System.currentTimeMillis();
System.out.println("StringBuilder对象执行20万次的时间为:" + (end4 - start4)
+ "毫秒\n");
/**
* 这种操作的执行时间为:9毫秒
* StringBuffer是值可变的,通过append方法,没有创建新的对象,因而效率很高
* 这是线程安全的。
*/
long start5 = System.currentTimeMillis();
for (int i = 0; i <= 2E5; i++) {
sBuffer.append(i);
}
long end5 = System.currentTimeMillis();
System.out.println("StringBufffer对象执行20万次的时间为:" + (end5 - start5)
+ "毫秒\n");
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99301.html