zoukankan      html  css  js  c++  java
  • 字符串String

    一、字符串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封装等。
  • 相关阅读:
    WebApi 安全认证
    Autofac 学习
    autofac实现批量注入
    Autofac -入门练习
    Struts2 Namespace_命名空间
    Deployment failure on Tomcat 6.x. Could not copy all resources
    chm 已取消到该网页的导航 或者 无法显示网页 的问题
    GPT 分区详解
    mount 中文手册
    rpm 中文手册
  • 原文地址:https://www.cnblogs.com/liupiao/p/9256381.html
Copyright © 2011-2022 走看看