java12-字符串操作类String、StringBuffer、StringBuilder

1.概述

  刚看了一下,我截图的文档字太小了好像有点看不清,请放大浏览器页面观看(Ctrl + 鼠标滚轮)或者到  官方API文档查看

  无论是哪种编程语言,对字符串的操作都是必不可少的。JAVA中为我们提供了三个操作字符串的类,分别是String、StringBuffer、StringBuilder,下面我们将会详细进行介绍。

  String、StringBuffer、StringBuilder类都是在java.lang包中定义的。所有的应用程序都可以使用他们。所有的这些类都被声明为final,这就意味着这些类不能有子类。这使得对于通用的字符串操作

  可以采用特定的优化用来提高性能,并且这三个类都实现了CharSequeue接口。

  提示:所谓的String类型对象中的字符串不可改变是指创建了String实例后不能修改实例的值。但是在任何时候都可以修改String引用变量,使其指向其他String对象。

2. String类

  2.1 构造函数:

      String类有众多的构造函数。一般我们使用一个传入一个字符串的构造函数。当然,如果我们想创建一个空字符串,可以使用默认的构造函数。

      其它构造函数列表如下:

  2.2 其他方法

      这里也不再赘述,要学会查询文档! 这里给出常用函数列表:

 

  2.3 注意事项

      1. String 字符串是支持+号连接的,并且在编译时,String会将+号去掉,用来简化拼接方式。

      2. 当字符串与数字进行连接的时候,若字符串在数字之前,则将数字转换成字符串,然后进行连接;若数字在前,则先对数字进行计算,将计算的结果与字符串进行拼接。(仅限+号)

 1 public class TestString {
 2
 3     public static void main(String[] args) {
 4         String s1 = "abc"+ 5+2;  //直接拼接
 5         String s2 = 5+2+"abc"; //先计算后拼接
 6         String s3 = "abc"+5*2;//对于出去+号之外的都要先计算再拼接
 7         System.out.println(s1); //abc52
 8         System.out.println(s2); //7abc
 9         System.out.println(s3); //abc10
10     }
11
12 }

      3.equals 与 == 的区别:equals 是用来比较两个字符串的值是否相等(只要值相等即可,并不要求引用相同),而==是比较两个字符串的引用地址是否是同一个地址(尽管值相等,但是引用地址不一定相等)

public class TestString {

    public static void main(String[] args) {
        String s1 = new String("xiaobai");
        String s2 = new String("xiaobai");
        System.out.println(s1.equals(s2)); //true  值相等
        System.out.println(s1==s2); //false //不是相同的引用
    }

}

      4.字符串的单一性(常量保存):字符串是不可变对象,而且是存储在常量区的,意思就是说,如果常量区中有某一个字符串,当我们再次声明它时,jvm并不会为我们再创建一个新的字符串,而是将已经存在的字符串的引用返回。

public class TestString {
    public static void main(String[] args) {
        String s1 = "xiaobai";
        String s2 = "xiaobai";
        System.out.println(s1.equals(s2)); //true  值相等
        System.out.println(s1==s2); //true 常量单一
    }
}

3.StringBuffer类

  3.1 概述

      我们知道,String类对象一旦确定就不能再修改,因为String类中的字符存储数组是final的。java为我们提供了一个可以更改的字符串操作类:StringBuffer。

  3.2 构造函数

      同理,这里直接给出构造函数:

  3.3 其他方法

  3.4 注意事项

      1.StringBuffer 不支持直接字面量赋值(也就是说不能直接把String对象引用赋值给StringBuffer),必须使用new 的形式。

public class TestString {
    public static void main(String[] args) {
        StringBuffer s1 = "xiaobai"; //不合法
        StringBuffer sb = new StringBuffer("ssss"); //正确

    }
}

      2. StringBuffer 中的append方法可以进行链式调用,并且返回结果是最后一次链式调用的结果

public class TestString {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("xiao")
                .append("bai").append("ni").append("hao");
        System.out.println(sb); //xiaobainihao
    }
}

      3.StringBuffer是线程不安全的。

4.StringBuilder类

  4.1 概述

      我们上面有提到,StringBuffer不是同步的,也就是说是线程不安全的。StringBuffer的优势是在于得到更高的性能。若我们同时有多个线程修改这个字符串怎么保证线程安全?

      当然,我们可以选择加锁同步。不过java已经为我们提供了一个类——StringBuilder  该类与StringBuffer基本相同,只不过他是线程安全的。

  4.2 构造方法

      

  4.3 其它常用方法

        与StringBuffer 基本相同,这里不再进行展示。

  4.4 注意事项

        这里也没什么可说的,等想到了再回来补充。

5.String、StringBuffer、StringBuilder 比较

    这三个类的比较无非是效率(运行速度/内存占用)和线程安全上,

  首先我们来看一下速度:

    下面这段代码分别是创建和拼接一万个次的执行时间: 可以看出 执行时间效率 StringBuilder > StringBuffer > String

    造成这种情况的原因也很简单,因为String 是单一实例(final)每次都要创建新对象并修改引用,所以最慢。

    而StringBuffer和StringBuilder的时间要比String短得多,原因也很简单,他只是在原有的字符串数组做添加操作,并不需要生成新对象和修改引用。

    StringBuilder比StringBuffer快的原因是StringBuffer实现了线程安全(synchronized),每次操作要获得锁,导致费时较长(但是要比String快的多)。

    

 1 public class TestString {
 2     public static void main(String[] args) {
 3         System.gc();
 4         long stringStart = System.currentTimeMillis();
 5         String s1 = new String();
 6         for(int i=0;i<100000;i++) {
 7             s1 =s1 + i;
 8         }
 9         long stringEnd = System.currentTimeMillis();
10         System.out.println("10w String instance coast: "+(stringEnd-stringStart)+" ms");
11
12         long stringBufferStart = System.currentTimeMillis();
13         StringBuffer s2 = new StringBuffer();
14         for(int i=0;i<100000;i++) {
15             s2 = s2.append(i);
16         }
17         long stringBufferEnd = System.currentTimeMillis();
18         System.out.println("10w StringBuffer instance coast: "+(stringBufferEnd-stringBufferStart)+" ms");
19
20         long stringBuilderStart = System.currentTimeMillis();
21         StringBuilder s3 = new StringBuilder();
22         for(int i=0;i<100000;i++) {
23             s3 = s3.append(i);
24         }
25         long stringBuilderEnd = System.currentTimeMillis();
26         System.out.println("10w StringBuilder instance coast: "+(stringBuilderEnd-stringBuilderStart)+" ms");
27         System.gc();
28     }
29 }

  然后再来看一下线程安全:

      由于String不支持修改,所以也就没有线程是否安全的说法(如果非要说有,那就是创建新对象时修改原来的引用地址为新地址,那一定是线程不安全的)。

      我们通过多线程程序测试:

      我分别在StringBuffer 和 StringBuilder 中循环了1000 次 ,每次拼接一个字母A ,同时开启三条线程进行这个操作。

      可以知道,如果线程安全 我们将会得到一个  3 * 1000 = 3000 长度的结果(一条线程拼接1000个 三条刚好3000个),通过结果我们可以看出,StringBuffer 是线程安全的,而SrtingBuilder的结果不足3000 说明发生了线程

      不安全的操作。(最直接的办法还是去jdk源码看一下,StringBuffer基本上每一个方法都有synchronized修饰)。

 

 1 public class TestString {
 2     public static void main(String[] args) throws InterruptedException {
 3         /**
 4          * @author xiaobai
 5          * 测试StringBuffer与StringBuilder的线程安全性
 6          * 实现两个自己的线程类
 7          * 分别创建三条线程 并发执行
 8          * 等待线程全部执行完,统计结果 比较
 9          *
10          * 若线程安全  应该是  3 * 1000 = 3000
11          */
12         Thread t1 =  new Thread(new MyStringBufferTest());
13         Thread t2 =  new Thread(new MyStringBufferTest());
14         Thread t3 =  new Thread(new MyStringBufferTest());
15
16         Thread t4 =  new Thread(new MyStringBuilderTest());
17         Thread t5 =  new Thread(new MyStringBuilderTest());
18         Thread t6 =  new Thread(new MyStringBuilderTest());
19
20         t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start();
21
22         while(Thread.activeCount()>1); //等待线程执行完
23
24         System.out.println("StringBuilder : "+MyStringBuilderTest.sbd.length());  //不一定是多少
25         System.out.println("StringBuffer : "+MyStringBufferTest.sbf.length()); // 一定是 3000
26
27     }
28 }
29
30 class MyStringBufferTest implements Runnable{
31     static StringBuffer sbf = new StringBuffer();
32     /**
33      * 进行1000 次拼接字符操作
34      * 中途sleep 10ms 使效果更好
35      */
36     @Override
37     public void run() {
38         for(int i=0;i<1000;i++) {
39             sbf.append("A");
40             try {
41                 Thread.sleep(10);
42             } catch (InterruptedException e) {
43                 // TODO Auto-generated catch block
44                 e.printStackTrace();
45             }
46         }
47     }
48 }
49
50 class MyStringBuilderTest implements Runnable{
51     static StringBuilder sbd = new StringBuilder();
52     /**
53      * 进行1000 次拼接字符操作
54      * 中途sleep 10ms 使效果更好
55      */
56     @Override
57     public void run() {
58         for(int i=0;i<1000;i++) {
59             sbd.append("A");
60             try {
61                 Thread.sleep(10);
62             } catch (InterruptedException e) {
63                 // TODO Auto-generated catch block
64                 e.printStackTrace();
65             }
66         }
67     }
68 }

结果:

  比较结论:

      效率上  : 由快到慢  StringBuilder > StringBuffer > String

      线程安全性: String  不安全   StringBuilder 不安全  StringBuffer 安全

     

    

      

原文地址:https://www.cnblogs.com/xiaobai1202/p/10896325.html

时间: 2024-10-08 13:20:13

java12-字符串操作类String、StringBuffer、StringBuilder的相关文章

字符串的使用(string,StringBuffer,StringBuilder)

String中==与equals的区别:==比较字符串中的引用相等equals比较字符串中的内容相等(因为字符串有重写equals方法) 例子: /************ String中的equals与== *****************/ /*  * ==比较字符串中的引用相等  * equals比较字符串中的内容相等(因为字符串有重写equals方法)  */// public static void main(String[] args) {//  String s1 = new S

重温java中的String,StringBuffer,StringBuilder类

任何一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类常用的有 3 个: String.StringBuffer.StringBuilder. 它们的异同点: 1) 都是 final 类, 都不允许被继承; 2) String 长度是不可变的, StringBuffer.StringBuilder 长度是可变的; 3) StringBuffer 是线程安全的, StringBuilder 不是线程安全的. String 类已在上一篇随笔 小瓜牛

转:String StringBuffer StringBuilder区别

转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,

String, StringBuffer, StringBuilder比较

1.见API: String是不可变的字符序列: StringBuffer是线程安全的,可变的字符序列: StringBuilder是可变的字符序列: StringBuffer与String的区别是StringBuffer是可变的(StringBuffer看做可变的String),StringBuffer中含有的字符序列和自身长度可随着方法调用而改变:StringBuffer在多线程环境中是安全的,必要的方法都是同步的,因而在某一特定实例上的所有方法就像被依次执行一样,与所有方法依次执行的结果一

String StringBuffer StringBuilder (转)

转自:http://www.iteye.com/topic/522167 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建        1.关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hello world"); 问题是参数"Hello world"是什么东西,

String/StringBuffer/StringBuilder基础

String类:特点: 1)字符串字面值"hello"可以看做一个字符串对象 2)字符串是常量,一旦被赋值,就不能被改变. 构造: public String() public String(byte[] bytes) public String(byte[] bytes,int index,int length):表示从该字节数组的offset索引处开始获取length个字节数结合成字符串 public String(char[] value) public String(char[

关于Java基础知识 String StringBuffer StringBuilder三者的区别

Java基础中String StringBuffer StringBuilder 以下介绍 相同点:String,StringBuffer,StringBuilder最终底层存储与操作的都是char数组,StringBuffer和StringBuilder都继承了AbstractStringBuilder 不同点:String:char数组是final的,不可变,修改String时实际上是new一个新String对象返回,线程安全,频繁的增删操作时不建议使用 StringBuffer:线程安全(

Java杂谈之StringBuffer----兼带String,StringBuffer,StringBuilder的区别

在Java中,用到最多的当属String类型的数据了 而这一点就要涉及String , StringBuffer , StringBuilder这三大类 下面主要来比较一下String和StringBuffer的区别,因为StringBuffer和StringBuilder 太相似,所以就不拿来比较了. 提及一下,StringBuffer和StringBuilder的区别 从安全性来说,StringBuffer更安全,StringBuffer主打线程安全 从执行效率来说,StringBuilde

String StringBuffer StringBuilder 对比

1.StringBuffer是线程安全的,StringBuilder是非线程安全的 2.对String的修改其实是new了一个StringBuilder并调用append方法,然后调用toString返回一个新的String. StringBuffer是在StringBuilder基础上加锁,加锁是一个重量级的操作,需要调用操作系统内核来实现,比较耗时. 因此效率明显有:String<StringBuffer<StringBuilder; 但是这个并不是绝对的,因为JVM会对String进行优