热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详细讲解String拼接原理,介绍StringBuilder和StringBuffer

?目录?0、思考?‍♂️1、讲解String拼接字符串原理Ⅰ底层字符接实现逻辑Ⅱ使用不同方法拼接字符串事

?目录?

0、思考?‍♂️

1、讲解String拼接字符串原理

Ⅰ底层字符接实现逻辑

Ⅱ使用不同方法拼接字符串事件比较

Ⅲ了解StringBuilder类修改内部字符串过程

2、介绍StringBuilder和StringBuffer及一些常用的方法

3、StringBuilder和StringBuffer区别

拓展:如何打开字节文件 


0、思考

        我们都知道真正修改一个String的内容是很难的,而我们平常却可以通过‘+=’来拼接字符串

public static void main(String[] args) {
String str = new String("Hello");
str += " World";
System.out.println(str);
}

         这是为什么呢?我们接着往下看。

1、讲解String拼接字符串原理

Ⅰ底层字符接实现逻辑

        我们来看一下上述代码的底层实现逻辑

          我们发现,当我们执行 “str += " World";”时底层其实走四步

  1. 先创建一个StringBuilder对象,并调用无参数的构造方法。
  2. StringBuilder对象调用append方法,把str内部 “Hello” 拼接到内部。
  3. StringBuilder对象再次调用append方法,把 " World" 拼接到内部。
  4. 最后StringBuilder对象调用toString方法,把拼接好的字符串传给str。

"":表示构造方法

()V:表示无参数的构造方法

 上述代码其实就等同于

public static void main(String[] args) {
String str = new String("Hello");

StringBuilder sb = new StringBuilder();
sb.append(str);
sb.append(" World");//拼接字符串
str = sb.toString();
System.out.println(str); //输出Hello World
}

所以我们每次拼接字符串时,都会创建一个对象进行该操作,而非在String内部进行。

注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法

Ⅱ使用不同方法拼接字符串事件比较

        我用两种方法拼接字符串,我们来看一下各种运行时间

public static void main(String[] args) {
//普通方法拼接
long start = System.currentTimeMillis();
String s1 = "";
for(int i = 0; i <10000; ++i){
s1 += i;
} long end = System.currentTimeMillis();
long time = end-start;
System.out.println("普通方法拼接时间:"+ time);

//用StingBuilder类拼接
start = System.currentTimeMillis();
StringBuilder s3 = new StringBuilder();
for(int i = 0; i <10000; ++i){
s3.append(i);
} end = System.currentTimeMillis();
time = end-start;
System.out.println("StringBuilder 拼接时间:"+ time);

}

 结果如下:

 我们用直接使用String类拼接的字符串的话,每拼接一次就会创建一个新的对象,次数一多运行时间就会变长。所以当我们频繁修改字符串的情况考虑使用StringBuilder类进行操作。 

我再举一个LeetCode上实际操作的例题,如下:

StringBuilder类拼接 1ms

普通拼接23ms

 大家感兴趣了,可以去做一下这道题:根据二叉树创建爱字符串

Ⅲ了解StringBuilder类修改内部字符串过程

我们看下图

        首先在栈中创建一个StringBuilder变量sb,然后在堆中开辟一块空间,被sb引用。

append方法我们可以看做把参数传给 StringBuilder对象

       当sb第一次调用append方法时,编译器会先把“Hello”放到字符串常量池中,然后再把“Hello”传给sb引用对象。

       当sb第二次调用append方法时,编译器同样会先把 " World" 放到字符串常量池中,但此刻 sb 并不会new一个新的对象来接受append方法传来的 " World",而是在原来的对象内部直接进行拼接。

 我们观察 append方法 就会发现,append方法最后返回的是 "this"!也就是原来的对象。

 

 这也就是为什么StringBuilde对象能修改字符串的原因。

2、介绍StringBuilder和StringBuffer及一些常用的方法

   上面我们介绍了 StringBuilder,其实为了方便字符串的修改,Java中又提供StringBuffer类。

    这两个类的大部分功能是相同的。如下

public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("你好!");
sb.append("我是威威");
String str = sb.toString();
System.out.println(str);
}

      

 而除了append和toString之外,StringBuilder和StringBuffer中包含各种各样的方法。

这里介绍一些常用的,其它需要用到了大家可参阅 StringBuilder在线文档

 以下以StringBuilder为例,StringBuffer中方法类似

方法说明
StringBuff append(String
str)
在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、
double、float、int、long、Object、String、StringBuff的变量
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取底层保存字符串空间总的大小
void ensureCapacity(int
mininmumCapacity)
扩容
void setCharAt(int index,
char ch)
将index位置的字符设置为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int
fromIndex)
从fromIndex位置开始查找str第一次出现的位置
int lastIndexOf(String str)返回最后一次出现str的位置
int lastIndexOf(String str,
int fromIndex)
从fromIndex位置开始找str最后一次出现的位置
StringBuff insert(int
offset, String str)
在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuffer
deleteCharAt(int index)
删除index位置字符
StringBuffer delete(int
start, int end)
删除[start, end)区间内的字符
StringBuffer replace(int
start, int end, String str)
将[start, end)位置的字符替换为str
String substring(int start)从start开始一直到末尾的字符以String的方式返回
String substring(int
start,int end)
将[start, end)范围内的字符以String的方式返回
StringBuffer reverse()反转字符串
String toString()将所有字符按照String的方式返回

3、StringBuilder和StringBuffer区别

为了对比StringBuilder和StringBuffer,我们来看一下他俩 append方法的具体代码

 我们发现,StringBuffer的append方法中,多了一个 synchronized,而 synchronized 含义是保护线程安全。平时遇到多线程时,用StringBuffer的比较多。

所以StringBuilder和StringBuffer区别在于:

        StringBuffer采用同步处理,属于线程安全操作

        StringBuilder未采用同步处理,属于线程不安全操作

拓展:如何打开字节文件 

我们在idea操作中,点击上面的小框

 点击后,找到Openin后点击Explorer,这时会弹出一个文件夹。

 点击 2022-7-12,找到out文件,进去点击production,再点击 2022-7-12,之后就能看见我们.class文件。

这里 2022-7-12 是我自己创建的文件名,而且我的 .class 文件在 demo2 包中,所以多跳了一步。

然后按着Shift键,右键点击 .class 文件,然后点击 “PowerShell”,就会弹出一个窗口

尽量点击文件中间空白部分,部分可能找不到 “PowerShell”,这个选项

 接着我们在窗口中输入 javap -c 文件名,就能看到我们代码编译后字节码啦 

 

到此,本节内容就讲完了,有错误的地方希望大家能批评指正,别忘了点赞?+收藏⭐️哦 

      ?  关注我!带来等多精彩??


版权声明:本文为weixin_53564801原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_53564801/article/details/125783453
推荐阅读
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了在PostgreSQL中批量导入数据时的优化方法。包括使用unlogged表、删除重建索引、删除重建外键、禁用触发器、使用COPY方法、批量插入等。同时还提到了一些参数优化的注意事项,如设置effective_cache_size、shared_buffer等,并强调了在导入大量数据后使用analyze命令重新收集统计信息的重要性。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了StartingzookeeperFAILEDTOSTART相关的知识,希望对你有一定的参考价值。下载路径:https://ar ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • 流数据流和IO流的使用及应用
    本文介绍了流数据流和IO流的基本概念和用法,包括输入流、输出流、字节流、字符流、缓冲区等。同时还介绍了异常处理和常用的流类,如FileReader、FileWriter、FileInputStream、FileOutputStream、OutputStreamWriter、InputStreamReader、BufferedReader、BufferedWriter等。此外,还介绍了系统流和标准流的使用。 ... [详细]
  • 总结一下C中string的操作,来自〈CPrimer〉第四版。1.string对象的定义和初始化:strings1;空串strings2(s1);将s2初始 ... [详细]
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼*madebyebhrz*#include#include#include#include#include#include#include ... [详细]
author-avatar
王妃2502872393
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有