Java--String类(StringBuilder与StringBuffer)

news2024/9/21 8:02:40

String类的特征:

        String类的特点:

1. String 类在设计时就是不可改变的, String 类实现描述中已经说明了

        String部分源码如下:

2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
        例如replace方法:

   public static void main(String[] args) {
        String s1 = "abcdef";
        String s2 = s1.replaceAll("a","b");
        System.out.println(s2);
    }

        我将所有的a换成b,此时究竟是在原来的字符串基础上改呢?还是new了一个新的String类?

源码如下:

        

里面确实new了一个新的String类!!!

注意:

final 修饰类表明该类不想被继承, final 修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内 容是可以修改的

例如: 

 public static void main(String[] args) {
        final int array[] = {1,2,3,4,5};
        int arr[] = {1,2,3};
        array[0] = 100;
        System.out.println(Arrays.toString(array));
// array = new int[]{4,5,6}; // 编译报错:Error:(19, 9) java: 无法为最终变量array分配值
为什么 String 要设计成不可变的 ? ( 不可变对象的好处是什么 ?) ( 选学 )
1. 方便实现字符串对象池 . 如果 String 可变 , 那么对象池就需要考虑写时拷贝的问题了 .
2. 不可变对象是线程安全的.
3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap

字符串修改:

        刚刚解释完,String中的字符串中的char[]数组引用被final修饰,不可再引用其他对象!!
所以要想修改字符串肯定是new一个新的String引用其他字符串!

    public static void main(String[] args) {
        String s = "hello";
        s += " world";//s = s+"world"
        System.out.println(s); // 输出:hello world
    }

 我们可以从反汇编代码的角度观察一下:

 我们也可以用另一套代码写出同样的效果:

    public static void main(String[] args) {
        String s = "hello";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(s);
        stringBuilder.append("world");
        s = stringBuilder.toString();
        System.out.println(s);
    }

通过反汇编可以看到本质,相当于new了一个新的对象,也就是一共有三个对象参加这次运行。有人问了,哪有三个对象,我怎么看不到。

我们一起来分析一下:

s是不是一个对象!

world也是一个对象!

注意,这里的toString也会返回一个新的对象:
源代码如下:

所以说最后肯定是一个新的对象,只不过是s引用了这个新的对象!!

这时候应该提出疑问,这个StringBuilder这个类是干什么的??

接下来一探究竟:

StringBuilder类与StringBuffer类:

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

StringBuilder:

StringBuilder方法也是不可被继承的,而且继承了父类AbstractStringBuilder类,同时还有两个接口!

构造函数:

StringBuilder构造函数有好多重载:

例如:

1、无参构造:
                

2、传整型构造:

3、传字符串构造:

那么每次构造如果调用了super(),这个究竟是干什么的,得从父类入手:

AbstractStringBuilder类:

        

我们发现父类中有两个成员变量:

有一个是字符数组,一个是整型。

而且如果是传带有参数的super会调用第二个构造函数,我们发现其实他是在new一个大小为capacity的字符数组!!

也就是它的底层是字符数组,在字符数组的基础上进行修改,也就不会多次new性的对象,提高性能!

append方法:

该方法就可以实现追加功能,也就是修改字符串,他是怎么实现的呢?

   public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

 当然append方法也有许多重载的方法,传入的参数有所差异。

就拿传一个字符串类型为例:
我们可以不用去管具体的实现细节,但是我们可以看出,在这个过程中没有再new一个新的对象,而且最后返回的还是自己。

这里就与String类型中的拼接字符串是有区别的了!!

我们可以用Stringbuilder类中的append方法完成拼接:

    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("abcd");
        stringBuilder.append("efg");
        System.out.println(stringBuilder);
    }

 注意:最后打印的时候直接传入stringbuild即可。

reverse反转字符串:

        这个方法也很厉害,在StringBuilder类的方法中有一个方法可以直接反转字符串!!

例如:

    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("abcdef");
        stringBuilder =  stringBuilder.reverse();
        System.out.println(stringBuilder);
    }

注意:

reverse方法的返回值是stringbuilder类型!!

StringBuffer:

StringBuffer和StringBuilder是差不多的,包括一些方法,用法都是差不多的。

但是唯一的区别是什么:

 我们需要关注一下它的append方法:

我们发现类比StringBuilder多了一行代码:

这行代码是干什么的呢?

这行代码可以理解为是一把锁,当程序运行时会所起来,结束后才会解开:

主要运用在多线程中!

 String、StringBuilder、StringBuffer的区别:

String 的内容不可修改, StringBuffer StringBuilder 的内容可以修改 .
StringBuffer StringBuilder 大部分功能是相似的
StringBuffer 采用同步处理,属于线程安全操作;而 StringBuilder 未采用同步处理,属于线程不安全操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

string的模拟实现and友元

一、引言 “知所从来,方知其往。”只有了解一个物体的构造才能更好的使用它。正所谓“不入虎穴,焉得虎子。”那我们学会使用一个类了,可不可以建造一个简易的类和对象出来呢?答案显而易见。因为这是C的内容,所以我们用…

C++八股文之STL篇

🤖个人主页:晚风相伴-CSDN博客 思维导图链接:STL 持续更新中…… 💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧 &#x1f64…

找搭子是什么意思?有没有找搭子的平台?靠谱找搭子软件推荐!

“找搭子” 指寻找在特定活动或兴趣方面有共同爱好的伙伴。比如饭搭子一起吃饭,运动搭子共同健身。它满足人们在特定场景下的社交需求,让生活更丰富有趣,是一种新型社交方式。以下是国内排名靠前的找搭子平台 1. 咕哇找搭子小程序&#xff1a…

Mac下nvm无法安装node问题

背景 最近换用mac开发,然后使用nvm(版本0.40.1)进行node安装的时候出现了一些问题 使用 nvm ls-remote发现只有 iojs 版本 原因可能是nodejs升级了某个协议导致的 解决方案 可以使用 NVM_NODEJS_ORG_MIRRORhttp://nodejs.org/dist nvm ls-re…

Cartographer源码理解

一、前言 最近一个半月,利用空余时间对Cartographer源码进行了简单的阅读,在这里做了个简单梳理,和大家分享交流。 cartographer源码量其实是有点大的,逐行逐句去解释实在是有心无力了,而且已经有大佬做了类似的事情…

分治算法归并排序

分治算法 基本概念 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 分治法的基本步骤 分治法在每一层递归上都有三个步骤: step1分…

单细胞CCA整合流程学习(SeuratV5/V4)

CCA(Canonical Correlation Analysis)和 Harmony 是两种常用于单细胞 RNA 测序(scRNA-seq)数据整合和批次效应校正的方法。 CCA 通过计算两个(或多个)数据集的线性组合,使这些组合之间的相关性…

1、vectorCast单元测试常用操作

一、自动创建测试工程 1、设置工作目录 进入软件主页面,点击file,选择set working directory,随便选择一个保存该项目的目录即可。 2、创建一个空工程 编译器选择vector自带的编译器,vectorCast MinGW C。 此时项目工程就创建好了 2.1、配置编译器节点 点击编译器节点…

JAVA毕业设计173—基于Java+Springboot+vue3的酒店民宿管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3的酒店民宿管理系统(源代码数据库)173 一、系统介绍 本项目前后端分离(可以改为ssm版本),分为用户、员工、管理员三种角色 1、用户&#xff1a…

Nowcoder—链表的回文结构

题目描述 题目分析 1.回文结构是指一个序列或字符串从前往后读或从后往前读都是相同的。 2.时间复杂度为O(n),说明循环只能有一层;空间复杂度为O(1),说明不能额外的申请空间。 3.链表的结点最多不会超过900个。 思路 1 思路1:…

2024年数字中国创新赛-MISC

1 wireshark-1 可以看到在theanswerishere.php执行了sql注入,所以存在漏洞的PHP页面名称是theanswerishere.php 2 wireshark-2 从以上漏洞测试我们发现在一共有三列 3 wireshark-3 从这里我们可以看到注入的列名是th1sfI4g 4 wireshark-4 从这里回显包我们能看到…

鸿蒙next web组件和h5 交互实战来了

前言导读 鸿蒙next web组件这个专题之前一直想讲一下 苦于没有时间,周末把代码研究的差不多了,所以就趁着现在这个时间节点分享给大家。也希望能对各位读者网友工作和学习有帮助,废话不多说我们正式开始。 效果图 默认页面 上面H5 下面ArkU…

深度学习--------------序列模型

目录 序列数据统计工具(方案一)马尔可夫假设(方案二)潜变量模型总结 序列模型基于马尔可夫假设方式该部分总代码 单步预测多步预测k步预测该部分总代码 序列数据 实际中数据是有时序结构的。 统计工具 在时间t观察带 x t x_t xt…

二叉搜索树(Java实现)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 1.概念 二叉搜索树又称二叉排序树,或者它是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都…

【kafka-01】kafka安装和基本核心概念

Kafka系列整体栏目 内容链接地址【一】afka安装和基本核心概念https://zhenghuisheng.blog.csdn.net/article/details/142213307【二】kafka集群搭建https://zhenghuisheng.blog.csdn.net/article/details/142253288 kafka安装和基本核心概念 一,kafka安装和基本核心…

MoneyPrinterTurbo 安装使用流程

项目地址: https://github.com/harry0703/MoneyPrinterTurbo 开发环境:mac 1 git 下载 # 下载代码到本地 git clone https://github.com/harry0703/MoneyPrinterTurbo.git cd MoneyPrinterTurbo2 docker 配源 在 docker 安装目录执行以下命令显示隐藏…

Spring模块详解Ⅳ(Spring ORM和Spring Transaction)

目录 Spring ORM(Object-Relational Mapping)作用核心组件使用步骤事务管理代码演示优点挑战总结 Spring Transaction(Spring事务管理)事务的基本概念Spring事务管理的类型声明式事务管理事务的传播行为(Propagation&a…

【LabVIEW学习篇 - 25】:JKI状态机

文章目录 JKI状态机JKI状态机安装JKI状态机的基本了解状态机的运行原理示例 JKI状态机 JKI状态机的核心就是队列消息状态机用户事件处理器模式,JKI状态机采用指定格式的字符串来描述状态。 JKI状态机并没有采用队列而是采用指定的字符串进行存储,它封装…

【论文阅读】PERCEIVER-ACTOR: A Multi-Task Transformer for Robotic Manipulation

Abstract transformers凭借其对大型数据集的扩展能力,彻底改变了视觉和自然语言处理。但在机器人操作中,数据既有限又昂贵。通过正确的问题表述,操纵仍然可以从变形金刚中受益吗?我们使用peract来研究这个问题,peract…

图解Redis 02 | String数据类型的原理及应用场景

介绍 在 Redis 中,String 是一种重要的数据类型,是最基本的 key-value 结构,在这个结构中, value 是一个字符串。value 所能容纳的数据最大长度为512M。 需要注意的是,这里的字符串不只指文本数据,它还可…