码迷,mamicode.com
首页 > 其他好文 > 详细

字符串String

时间:2018-07-03 00:16:52      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:new   特殊   方式   tac   不同的   span   rgs   build   关键字   

一、字符串String

1、字符串操作可以说是我们在java中使用最频繁的操作之一,String不是基本类型,而是一个引用类型,查看jdk源码可以知道String这个类是被final修饰的,这就意味着String是不能被继承的,类中的方法默认是final方法。这或许是对字符串String的一种保护。字符串使用非常简单,如下:

 1 public class Demo {
 2     public static void main(String[] args) {
 3         String str0 = null;
 4         String str1 = "test";
 5         String str2 = new String("test");
 6         System.out.println(str1.substring(1));
 7         System.out.println(str2.concat("hi"));
 8     }
 9     
10 }
  • 通过查看JDK文档会发现几乎每一个修改String对象的操作,实际上都是创建了一个全新的String对象。

2、字符串的特殊之处

 1 public class Demo {
 2     public static void main(String[] args) {
 3         String str0 = "demo";
 4         String str1 = new String("demo");
 5         String str2 = "demo";
 6         String str3 = new String("demo");
 7         
 8         System.out.println(str0==str1);
 9         System.out.println(str0==str2);
10         System.out.println(str1==str3);
11     }
12     
13 }

输出结果:

false
true
false

为什么有上面结果的差异呢?String str1 = "test"和String str2 = new String("test")的区别在哪里呢?在字符串中存在一个非常特殊的地方,一般推荐使用String str1 = "test"的形式。

String str0 = "demo";和String str2 = "demo";在编译期间生成字面常量和符号引用,运行期间字面常量"hello world"被存储在运行时常量池,当我们通过这个方式创建一个字符串的时候,首先会检查常量池中检查字面常量"demo"是否已经存在,如果存在,则直接将str0指向已经存在的字面常量,否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。而通过new的方式创建字符串对象,则是在堆区进行,通过new关键字每次都是新创建一个对象。因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。

3、字符串的连接操作

字符串的拼接的方式主要是有如下几种:+,+=,String的concat方法,以及借助StringBuild类的append方法。+,+=是java中仅有的两个被重载了的操作符,java中不允许程序员自己重载操作符。

 1 public class Demo {
 2     public static void main(String[] args) {
 3         String str0 = "demo";
 4         str0+="--next";
 5         System.out.println(str0);
 6         String str1 = "--next";
 7         String str3 = str0+str1;
 8         System.out.println(str3);
 9         
10         String str4 = str3.concat("--next");
11         System.out.println(str3);
12         System.out.println(str4);
13         
14         StringBuilder sb = new StringBuilder();
15         String str5 = sb.append(str4).append("--last").toString();
16         System.out.println(str5);
17     }
18     
19 }

输出结果:

demo--next
demo--next--next
demo--next--next
demo--next--next--next
demo--next--next--next--last

字符串可以通过上面三种方式拼接,那么他们之间除了用法的区别外,还有上面其他的不同之处?处理字符串的速度不同。通过一个测试类就能知道

 1 public class StringTest {
 2     public static void main(String[] args) {
 3         //1、+连接符
 4         long start1 = System.currentTimeMillis();
 5         String str1 = "hi";
 6         for(int i=0;i<10000;i++){
 7             str1+="hi";
 8         }
 9         long end1 = System.currentTimeMillis();
10         System.out.println("+ 消耗时间:"+(end1-start1)+"毫秒");
11         
12         //2、contact()
13         long start2 = System.currentTimeMillis();
14         String str2 = "hi";
15         for(int i=0;i<10000;i++){
16             str2=str2.concat("hi");
17         }
18         long end2 = System.currentTimeMillis();
19         System.out.println("+ 消耗时间:"+(end2-start2)+"毫秒");
20         
21         //2、contact()
22         long start3 = System.currentTimeMillis();
23         String str3 = "hi";
24         StringBuilder sb = new StringBuilder(str3);
25         for(int i=0;i<10000;i++){
26             sb.append("hi");
27         }
28         str3 = sb.toString();
29         long end3 = System.currentTimeMillis();
30         System.out.println("+ 消耗时间:"+(end3-start3)+"毫秒");
31     }
32 
33 }

输出结果:

+ 消耗时间:95毫秒
concat 消耗时间:35毫秒
append 消耗时间:1毫秒

出现上述结果的原因:

1)字符串的直接相加,效率非常高,例如:String str="hell"+"o",在编译期间优化成String str="hello",而String str="hell",str=str+"o"等同于str = new StringBuilder(str).append("b").toString();

2)concat方法是借助字符数组拷贝的形式操作字符串,数组的处理速度非常之快

3)append方法同样是借助字符数组进行字符串处理的,加长,然后拷贝。而上述结果差异是因为concat涉及的对象个数远大于append,对象的创建需要时间。

二、StringBuffer

StringBuffer和String一样都是用来存储字符串的,是一个可变的字符串对象,在内存使用方面优于String,通过它操作字符串的时候,不会产生新的字符串对象,使用比较简单。

 1 public class Demo {
 2     public static void main(String[] args) {
 3         StringBuffer sb = new StringBuffer("hello");
 4         sb.append("sss");
 5         System.out.println(sb);
 6         sb.insert(2, ‘A‘);
 7         System.out.println(sb);
 8         sb.delete(0, 2);
 9         System.out.println(sb);
10     }
11     
12 }

输出结果:

hellosss
heAllosss
Allosss

三、StringBuilder

StringBuilder也是一个可变的字符串对象,他与StringBuffer不同之处就在于它是线程不安全的,基于这点,它的速度一般都比StringBuffer快。与StringBuffer一样,StringBuider的主要操作也是append与insert方法。这两个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符添加或插入到字符串生成器中。与String和StringBuilder的使用场景不同。

  •  String:在字符串不经常变化的场景中可以使用String类,如:常量的声明、少量的变量运算等。
  •  StringBuffer:在频繁进行字符串的运算(拼接、替换、删除等),并且运行在多线程的环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装等。
  •  StringBuilder:在频繁进行字符串的运算(拼接、替换、删除等),主要在单线程环境中使用,如SQL语句的拼装、JSON封装等。

 

字符串String

标签:new   特殊   方式   tac   不同的   span   rgs   build   关键字   

原文地址:https://www.cnblogs.com/liupiao/p/9256381.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!