String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

这篇具有很好参考价值的文章主要介绍了String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文介绍了String类对字符串进行拼接的方法 和拼接字符串的效率分析 以及能对字符串内容进行修改的StringBuilder和StringBuffer类其常用方法和区别 , 最后介绍了两个字符串经典面试题

一.String类概括

1.String常用方法学习->2.String的不可变和字符串常量池->StringBuilder和StringBuffer

String类是Java中用来描述操作字符串的类
上两篇博客介绍了介绍了常用的方法,以及String的特性:String内容是不可变的以及字符串常量池,感兴趣的可以去看看…

二.StringBuilder和StringBuffer

StringBulder和StringBuffer是和String一样都是对字符串进行操作的类
而学了String后知道,String内容是不可变的,对String的内容进行修改都会创建一个新的字符串返回

而创建新的String对象比原字符串修改所耗费的时间空间更多,效率低很多

因此,java中提供的StringBuilder和StringBuffer是专门用来对字符串进行原地修改的类,并且它们都可以和String类之间进行相互转换

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
通过源码看到 这两个类的方法大致都相同,且都extends继承了AbstractStringBuilder类

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
而AbstractStringBuilder类 底层是存在一个value 数组引用和count变量的,其没有被private和final修饰 能够在StringBuilder和StringBuffer中访问到

value数组即维护的是字符串内容 , 而count记录的是value内有效的字符个数即真正的字符串长度

(因为value指向的字符数组长度是当前存放字符串的空间,还有预留的空间用来新增字符等, count记录的才是字符串真正的长度)

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的

1.字符串拼接

在String方法中提供concat和join方法 可以使字符串之间进行拼接

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

concat是成员方法,使一个字符串对象内容与另一个字符串对象进行连接成一个新的字符串对象返回
String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

join是静态成员方法, 方法第一个参数 是连接的分隔字符串, 后续2~n个是用来连接的字符串, 会将其拼接在一起 用一个参数做分隔(分隔连接的每段字符串,如果只有一段则不显示分隔符),最后返回此拼接的字符串对象

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

但上面这些方法并不具备将其他数据类型的数据拼接进字符串的功能因此使用这些方法还要拼接其他非String类型的数据还要将其先转换为字符串再进行拼接

而在Java中,String类型 用 + 连接 String字符串数据和任意类型数据 都可以使其简单快捷直接拼接为一个新字符串对象
示例:

public static void main(String[] args) {

        System.out.println("12"+3);
        System.out.println(3+"12");
        System.out.println(1+2+"12");
        System.out.println("12"+1+2);
        System.out.println(false+"12"+true);
        //代码输出结果是什么?
    }

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
字符串类型数据和任何数据类型数据 之间使用+运算,都可以拼接成一个新的字符串对象,

但注意要运算符的优先级, 1+2+“12” 是先计算1+2 结果为3 再3+“12"拼接成字符串"312”

“12”+1+2,是先"12"+1拼接成字符串"121" 再+2 拼接成字符串"1212"

boolean类型数据可以参与字符串拼接

“”+12 可以使 12数字拼接为字符串"12"

通过+号可以快速实现字符串拼接,这种用法很方便让我们使基本数据类型快速变为字符串类型

StringBuilder和StringBuffer也可以实现字符串拼接, 需要调用其内部的append方法:

public static void main(String[] args) {
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(1+2);
        stringBuilder.append(12);
        System.out.println(stringBuilder);
        stringBuilder.append(3);
        System.out.println(stringBuilder);
        stringBuilder.append(false);
        System.out.println(stringBuilder);
 }

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

可以看到通过StringBuilder对象 使用其append方法可以将任意数据类型拼接成一个字符串
String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
而append方法内部最后返回的都是StringBuilder对象本身,并没有创建新对象…

从运行效率上String类型使用+和其他数据拼接 和StringBuiler以及的append方法哪种更好?

此时可以使用Java内一种计算内部运行时间的方法System.currentTimeMillis()采取差值运算, 来分别测试这三个的运行时间…
示例:

public static void main(String[] args) {
        long start = System.currentTimeMillis();  // 计算当前内部运行时间
        String s = "";

        for(int i = 0; i < 10000; ++i){
            s += i;                             //字符串类型 加任意基本数据类型 都会拼接成一个新字符串再给s引用接收
        }   // 每+=一次 会额外创建三个对象
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");  // 需要加锁解锁
        for(int i = 0; i < 10000; ++i){
            sbf.append(i);                     //对字符串内的数组进行操作 不会创建额外字符串
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            sbd.append(i);                 //对字符串内的数组进行操作 不会创建额外字符串
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
通过运行结果可大概估计:拼接效率:String<StringBuffer<StringBuilder

为什么String类型使用+进行字符串拼接效率比StringBuilder和StringBuffer慢很多?

通过 javap -c 字节码文件 反汇编此文件, 能看到使用+号底层做了些什么事
String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
使用+进行拼接, 本质上是先new了一个StringBuilder对象,然后调用append方法将s字符串追加进去,再调用append 将i 追加进去, 最后调用了toString方法返回~

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
而StringBuilder重写了toString方法,其作用是 实例一个新String对象,
将StringBuilder继承的AbstractStringBuilder的value数组引用指向的数组 和 ,0 ,count作为参数传参调用其构造方法,

作用是 创建一个String对象 其内容是 value指向的数组对象 0~count之间的内容 (注意:String内的value是指向的新value数组)

可见:使用+号拼接字符串,在底层是使用了StringBuilder对象的append方法,最后返回的也是一个新String对象…

那在上述代码中, 使用for循环通过+号拼接了10000个i, 每次拼接都会创建一个StringBuilder对象和String对象, 可见完成此操作需要new如此多的对象,而且还要回收掉未被指向的String对象, 消耗非常大

而直接实例StringBuilder对象通过append追加字符串内容, 全部追加完成后最后只需要将StringBuilder对象转换String对象 进行一次操作即可, 在此操作里只额外实例化了两个对象, 开销比+号少的多

故:在使用大量字符串追加操作时, 不建议使用+号操作符进行拼接, 其性能远远低于用StringBuilder进行append拼接, 而使用StringBuilder效率比其他拼接方法效率更高

(“1”+“2” 字符串常量用+号拼接不会进行上述append在底层直接看成"12"字符串)

2.StringBuilder和StringBuffer常用方法和区别

StringBuilder和StringBuffer都能对字符串进行修改, 其内部大部分方法也是相同
以下是一些常用的其内能对字符串内容进行修改的方法如:

方法 作用
append() 在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量
void setCharAt(int index,char ch) 将index位置的字符设置为ch
insert(int offset, String str) 在offset位置插入:八种基类类型 & String类型 & Object类型数据
deleteCharAt(int index) 删除index位置字符
delete(intstart, int end) 删除[start, end)区间内的字符
replace(intstart, int end, String str) 将[start, end)位置的字符替换为str
reverse() 将字符串进原地逆置
toString() 将内容以String对象形式返回

以上是StringBulider和StringBuffer常用到的对字符串内容进行修改的方法,其内还有一些和Stirng类一样的方法如 indexOf(),具体可自己去了解

既然大部分方法都是相同的,那这两个类的具体区别在哪?

因为String类不能对字符串进行修改,其设计可以使线程更安全,每个线程对方法的调用都是创建新字符串对象, 而 StringBuilder能对字符串内容进行修改,那就会导致多个线程同时调用一个方法会产生一些问题… 此时正是要解决这个线程不安全的问题

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习
通过源码可以看到,StringBuffer内大部分的方法都有synchronized(同步) 关键字修饰 ,被此关键字修饰的方法即为同步方法, 其是线程安全的, 表示在多线程情况下, 不同线程同时调用这个方法时会将其上锁,同一时间只能有一个线程执行此方法,其它线程只能等待执行完这个方法解锁后才能一一执行此方法

而在上面StringBuffer 和StringBuilder 对象 对10000个i进行拼接时, StringBuilder比其效率高一点,也是因为 StringBuffer 执行方法时 还要 进行加锁解锁操作,此也是要消耗资源的…

故StringBuffer类用在多线程情况下,对字符串对象进行修改 而StringBuilder用在单线程情况下

3. 面试题:以下代码共创建多少个对象?

 public static void main(String[] args) {

        String str=new String("123");  // 创建多少个对象
        String str1=new String("1"+"2")+new String("3"); //创建多少个对象
//以上程序在运行时字符串常量都是第一次出现字符串常量池并不存在程序中的常量字符串
    }

在程序运行时,并 str代码 一个"123"对象并存放在字符串常量池里,new String()一个对象; 最后 创建了两个String对象

str1处 首先new了一个StringBuilder对象 再 new String() 一个对象 , “1”+“2” 底层直接编程成"12" 是一个String对象 , 再被拼接到StringBuilder中, 然后在new String对象, 然后"3"一个对象 , 再被拼接到StringBuilder对象中 , 最后 StringBuilder调用了toString又new了一个String对象 返回 , 最后 new了1个StringBuilder对象和五个String对象

注意str1最后接受的字符串内容是123 但是其和字符串常量池中的"123" 是不同的
字符串常量池是在编译时将其字符串常量"123"存放进去的, 而str1接受的是后续拼接出来的字符串123

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习

4.面试题: String 、StringBuilder和StringBuffer的异同

三者都是用来描述操作字符串的类

String类的内容是不可变的所有对String内容进行修改的操作都是创建新String对象

,StringBuilder和StringBuffer的内容都是可变的,常用来对字符串内容进行频繁修改时使用,

StringBuffer与StringBuilder大部分功能是相似的

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

三.总结

本文介绍了字符串拼接的方法 (String的成员方法concat和类成员方法join +号运算符拼接 StringBuilder和StringBuffer的append拼接 )以及各种拼接方法的效率 和底层反汇编分析, StringBuffer和StringBuilder的大部分对内容进行修改的方法,和其不同点, 以及两大字符串方面的面试题 及其分析

String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习文章来源地址https://www.toymoban.com/news/detail-448515.html

到了这里,关于String类的学习笔记(下):字符串拼接以及StringBuilder和StringBuffer的学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【从零学习python 】06. Python中运用算数运算符进行计算和字符串拼接

    现代的计算机和依赖计算机的设备里都用到二进制(即0和1)来保存和表示数据,一个二进制表示一个比特(Bit)。 在二进制的基础上,计算机还支持八进制和十六进制这两种进制。 除了计算机里的进制以外,我们生活中经常用到的是十进制。 Python语言支持二进制、八进制、十六

    2024年02月13日
    浏览(52)
  • mysql 拼接字符串,截取字符串 常用方式

    1,拼接字符串常用:CONCAT(‘需要拼接的字符串’,列名) CONCAT(\\\'+\\\',b.Telephone)查询出号码,前边加上+号 2,分割字符串 substring_index(b.Telephone,\\\'+\\\',1) 用从左往右的第一个+分割电话号码,获取分割后的从左往右的第一个字符串 比如 86+133333333 执行完后 为 86 substring_index(b.Telephone,\\\'+\\\',

    2024年02月14日
    浏览(49)
  • Python_字符串(字符串拼接:join() 与 +拼接符两种方法效率对比)

    运算结果如下图所示: 显然,在循环1000000次的前提下,字符的join()运算效率远远高于使用+拼接符的运算。 其根本逻辑在于: 对于简单的+运算符,字符串每次相加都会创建一个新的对象。较为费时。 而对于join(),其用于列表内字符串的相加,列表中字符串的相加并不会创建

    2023年04月24日
    浏览(54)
  • shell 拼接字符串,出现后面的字符串覆盖前面的字符串问题

    shell 拼接字符串语法很简单两个参数并排前后写上接口,如下 str1=www str2=bbb s t r 1 str1 s t r 1 str2 的结果未 wwwbbb 有时会出现如下问题: 在拼接字符串的时候,后面的字符串将前面的字符串覆盖了。 shell的内容如下: #!/bin/bash date_str=“ date +%Y%m%d ” echo $date_str python_file_name=\\\" 1

    2024年02月09日
    浏览(50)
  • JS中字符串切割为数组/数组拼接为字符串

    (1)语法格式: 其中所选分隔符使用双引号(“”)或者单引号(‘’)括起来; 所生成的数组会存放于前面定义的数组变量中。 (2)样例: JS代码: 运行结果: (3)其他用法: ①当所选分隔符为空时,返回的数组即将每个字符分割出来: JS代码: 运行结果: ②分隔

    2024年02月12日
    浏览(53)
  • C++ 字符串拼接

    第一种方法直接是字符串之间相加 第二种方法使用append append 可以设置参数  例如 append(“s1”,3) 这就是把s1前三位拼接 例如下面的就是把adbc的前2位,也就是ab 拼接到s1 上面 打印结果   append(s1,2,4)设置2个参数,就是从第2位开始后面的四位拼接 下面的就是abcdefg从第

    2024年02月16日
    浏览(42)
  • SQL字符串拼接

    ①CONCAT() 拼接字符串基本型: SELECT CONCAT ( lastname , firstname) AS student_name FROM kalacloud_student; ②使用空格拼接字符串: 仍然使用 SELECT CONCAT() 命令,空格需要使用\\\' \\\' 两个单引号引起来。SELECT CONCAT(firstname, \\\' \\\', subject) AS studentDetail FROM kalacloud_student; ③使用特殊符号拼接字符串: S

    2024年02月17日
    浏览(42)
  • Java中字符串占位替换、字符串拼接、字符串与Collection互转的方式

    1、String.format 最原始最基础的方式。 使用%来表示占位,后面跟上不同的标识符,用于限定这个占位符的参数类型,由jdk原生提供支持。 示例: 2、MessageFormat 如果遇到一个参数需要替换模板中多个占位的场景,更友好的方式是MessageFormat,由jdk原生提供支持。 示例: 举例:将

    2024年02月16日
    浏览(57)
  • 【C#】字符串拼接相关

    目录 1.字符串拼接方式1 用+号进行字符串拼接 复合运算符 += 2.字符串拼接方式2 3.控制台打印拼 4.例子  之前的算数运算符 只是用来数值类型变量进行数学运算的 而 string 不存在算数运算符 不能计算 但是可以通过+号来进行字符串拼接 用+号进行字符串拼接 复合运算符 += 按数

    2024年02月04日
    浏览(41)
  • Java Stream 拼接字符串

    一、使用背景                   在开发过程,有时候需要将集合结果转化成字符串,按照指定的字符分隔进行拼接,java stream的收集器提供相应的API,操作简单方便,下面直接上示例代码; 二、API操作

    2024年04月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包