zoukankan      html  css  js  c++  java
  • Java基础之:StringBuffer与StringBuilder

    Java基础之:StringBuffer与StringBuilder

    StringBuffer

    StringBuffer是final类,实现了Serializable接口,可以保存到文件,或网络传输。继承了抽象类AbstractStringBuilder,StringBuffer继承了AbstractStringBuilder类的char[] value属性,用于存放字符。

    所以对于Stringbuffer而言,字符串是可变的,因为保存字符串的char数组,没有被final修饰。

    String和StringBuffer的对比

    • String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更新地址,效率比较低。底层实现是private final char value[];

    • StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer更新是更新内容,不需要更新地址,效率较高,但对于StringBuffer而言,有一个字符串长度的限制,当超过限制时,就需要通过扩容来增加长度。即便如此,也是比String运用起来方便了很多。底层实现时char value[];

    在之前的博客“Java基础之:OOP——抽象类”中的最后一个案例,就体现了StringBuffer在拼接字符串上的速度远远优于String。其原理就是因为,StringBuffer底层不是final修饰的char[]数组。

    测试案例

    public class StringBuffer {
        public static void main(String[] args) {
    ​
            // TODO Auto-generated method stub
            long start = System.currentTimeMillis();
            StringBuffer s = new StringBuffer("");
            for (int i = 0; i < 80000; i++) {
                s.append("hello");
            }
            long end = System.currentTimeMillis();
            System.out.println("耗时=" + (end - start) + " length=" + s.length());
        }
    }

     

    由于StringBuffer中可以使用的方法大多都与String相同,所以这里不再介绍。

    应用案例

    输入价格,要求打印效果示例 7777123567.59=> 7,777,123,567.59 ;123,564.59 <= 123456.59

    package class_StringBuffer;
    import java.util.Scanner;
    public class ClassWork01 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            String in = scanner.next();
            StringBuffer sb = new StringBuffer(in);
            int index = sb.indexOf(".");
            if (index != -1) {
                for (int i = index - 3; i > 0; i -= 3) {    //直接先减掉一个3,就定位到需要插入逗号的位置
                    //if (i != index) {
                        sb.insert(i, ",");
                    //}
                }
            } else {
                for (int i = 0; i < sb.length(); i += 3) {
                    if (i != 0) {
                        sb.insert(i, ",");
                    }
                }
            }
            System.out.println(sb);
        }
    }

     

    StringBuilder

    • StringBuilder是一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(多线程问题,即在多个线程同时访问时出现问题)。该类被设计作为StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果不考虑线程安全问题,可以优先使用此类,在大多数情况下,它比StringBuffer要快。

    • 在StringBuilder中主要使用的是append与insert方法,可重载这些方法,以接收任何类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符。

    StringBuffer与StringBuilder都是可变序列,所以使用方法上是一样的。

     

    String、StringBuffer、StringBuilder的比较

    1. String:不可变字符序列, 效率低,但是复用率高。

    2. StringBuffer:可变字符序列、效率较高(增删)、线程安全(方法有synchronized)

    3. StringBuilder(JDK1.5):可变字符序列、效率最高、线程不安全(方法没有synchronized)

    4. String s = "a"; (创建了一个字符串)。String s += "b"; (再次创建字符串"ab")。实际上原来的字符串"a"已经被丢弃了,创建了一个新的字符串"ab"。如果多次执行这种修改操作,就会有大量的副本字符串对象被丢弃来内存中,降低效率。如果这种情况出现在循环语句中,会极大的影响性能。

    5. 结论:当需要频繁的修改字符串时,不要使用String类型声明字符串。

    测试案例

    public class StringVsStringBufferVsStringBuilder {
    ​
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    ​
            String text = ""; //字符串
            long startTime = 0L;
            long endTime = 0L;
            StringBuffer buffer = new StringBuffer("");//StringBuffer
            StringBuilder builder = new StringBuilder("");//StringBuilder
            
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 80000; i++) {
                buffer.append(String.valueOf(i));
            }
            endTime = System.currentTimeMillis();
            System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
            
            
            
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 80000; i++) {
                builder.append(String.valueOf(i));
            }
            endTime = System.currentTimeMillis();
            System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
            
            
            
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 80000; i++) {
                text = text + i;
            }
            endTime = System.currentTimeMillis();
            System.out.println("String的执行时间:" + (endTime - startTime));
    ​
        }
    }
    

      


     

  • 相关阅读:
    Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)
    2017年浙江省赛总结
    UVALive 3716 DNA Regions ——(扫描法)
    UVALive 3716 DNA Regions ——(式子变形)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    Egyptian Collegiate Programming Contest (ECPC 2015) C题 Connecting Graph
    UVALive 4726 Average ——(斜率优化DP)
    CodeForces 494B Obsessive String ——(字符串DP+KMP)
    [BUUOJ记录] [极客大挑战 2019]RCE ME
    [BUUOJ记录] [GXYCTF2019]BabySQli
  • 原文地址:https://www.cnblogs.com/SongHai/p/14174728.html
Copyright © 2011-2022 走看看