Stringbuilder和String的区别,一文弄清String、StringBuilder、StringBuffer

在这里插入图片描述

Stringbuilder和String的区别,一文弄清String、StringBuilder、StringBuffer

情景再现

今天刷题,有关字符串的操作,采用String的时候,总会出现超出时间限制,当我改成用StringBuilder时时间就会下降很多。

那么同样时间复杂度的算法,为什么这两个操作所耗费的时间相差会这么大呢。

在这里插入图片描述

1. 可变性

String修改的底层逻辑

创建 String 对象的过程
  • 当你创建一个 String 对象时,例如通过 new String("Hello"),Java 会在堆内存中为这个字符串分配空间。这个空间的大小取决于字符串的实际内容,即字符的数量。

  • String 对象内部使用一个 char 类型的数组来存储字符数据。这个数组的长度在创建时就已经确定,等于字符串的长度。

修改 String 对象
  • 由于 String 对象是不可变的,任何看似修改 String 的操作(如拼接、替换等)都会生成一个新的 String 对象。

  • 例如,当你执行str = str + "World";时,Java 会创建一个新的String对象,这个新对象包含原始字符串和 “World” 的组合。这个过程涉及到:

    • 创建一个新的 char 数组,长度为原始字符串长度加上 “World” 的长度。
    • 将原始字符串的字符复制到新数组的相应位置。
    • 将 “World” 的字符复制到新数组的末尾。
    • 返回这个新创建的 String 对象。
  • 原来的 String 对象(如果不再被引用)将变得无用,最终会被垃圾回收器回收。

SringBuilder的底层逻辑

创建StringBuilder的过程
  • StringBuilder 内部使用一个可变的 char 数组来存储字符串数据。这个数组在 StringBuilder 对象创建时初始化,并随着字符串内容的修改而动态调整大小。
  • StringBuilder 有两个重要的属性:capacity(容量)和 length(长度)。capacity 是内部数组能够存储的最大字符数,而 length 是当前字符串的实际长度。length 总是小于或等于 capacity
修改StringBuilder的过程
  • 当你向 StringBuilder 中添加字符,并且当前的 capacity 不足以容纳更多的字符时,StringBuilder 会自动进行扩容。扩容通常涉及到创建一个新的更大的数组,并将旧数组中的字符复制到新数组中,然后添加新的字符。
  • StringBuilder 在扩容时,通常会将容量增加到当前 capacity 的两倍,或者如果 capacity 很小,可能会增加一个固定的值(如 16)。
  • StringBuilder 提供了多种方法来修改字符串,如 appendinsertreplacedelete 等。这些方法直接在内部数组上进行操作,而不是创建新的字符串对象。例如,append 方法会检查当前 capacity 是否足够,如果不够,会先进行扩容,然后将新字符添加到数组的末尾。

2. 线程安全性:

如何理解线程安全性

当我们的项目使用多线程过程中。比如某一个变量,线程A去修改的同时,线程B也去修改。

因为多线程是并发的,那么在两个线程对这个变量修改之后会出现该变量起数据不一致或者程序运行出错的问题。

线程安全性的重要性

线程安全性在支付场景十分常见,简单的情景再现一下。假设有一个银行账户类 BankAccount,其中包含一个 balance 属性,表示账户的余额。现在有两个线程 A 和 B,它们都需要从同一个账户中取钱。

class BankAccount {
   
    private double balance;

    public BankAccount(double balance) {
   
        this.balance = balance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值