zoukankan      html  css  js  c++  java
  • String、StringBuffer与StringBuilder之间区别

    概述

    如下图

    String StringBuffer StringBuilder
    String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间 StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量 可变类,速度更快
    不可变 可变 可变
    线程安全 线程不安全
    多线程操作字符串 单线程操作字符串

    Java String 类——String字符串常量

    简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。

    我们来看一下这张对 String 操作时内存变化的图:

    我们可以看到,初始 String 值为 “hello”,然后在这个字符串后面加上新的字符串 “world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了 “hello world” 字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关的操作,就需要使用 Java 提供的其他两个操作字符串的类—— StringBuffer 类和 StringBuilder 类来对此种变化字符串进行处理。

    StringBuffer 和 StringBuilder 的 3 个区别

    先看看 StringBuffer 和 StringBuilder 的类结构吧:

    其实很简单,就是继承了一个抽象的字符串父类:AbstractStringBuilder。下面我们再来看看它们的三个区别。

    区别1:线程安全

    StringBuffer:线程安全,StringBuilder:线程不安全。因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 并没有 synchronized 修饰。

    StringBuffer 代码片段:

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    

    区别2:缓冲区

    StringBuffer 代码片段:

    private transient char[] toStringCache;
    
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
    

    StringBuilder 代码片段:

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }
    

    可以看出,StringBuffer 每次获取 toString 都会直接使用缓存区的 toStringCache 值来构造一个字符串。

    而 StringBuilder 则每次都需要复制一次字符数组,再构造一个字符串。

    所以,缓存冲这也是对 StringBuffer 的一个优化吧,不过 StringBuffer 的这个toString 方法仍然是同步的。

    区别3:性能

    既然 StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,所以毫无疑问,StringBuilder 的性能要远大于 StringBuffer。

    总结

    所以,StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景,如果是单线程场合 StringBuilder 更适合。

    参考文章:

    https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303

    https://segmentfault.com/a/1190000017909550

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/youcoding/p/14092242.html
Copyright © 2011-2022 走看看