【java】关于String、StringBuffer和StringBuilder的那些事

   在之前的文章中我们曾简单介绍过String这个引用类型变量,其实它还有许多特性,还有StringBuffer和StringBuilder这两个方法在字符串操作中也有非常重要的地位,接下来就由小编带大家梳理一下吧👊

ef22313ff90042009f01c78f367a4671.jpg

 

目录

一、String

1、构造方法

2、字符串的不可变性

3、字符串的比较

4、 String的常用方法:

二、StringBuider和StringBuffer

1、字符串的拼接

2、StringBuider与StringBuffer

总结

 


 

一、String

1、构造方法

String类提供的构造方式非常多,常用的就以下两种:
 
public static void main(String[] args) {
    // 使用常量串构造
    String s1 = "hello";
    System.out.println(s1);

    // 直接newString对象
    String s2 = new String("hello");
    System.out.println(s1);


}

注意:

1、String是引用类型,内部并不存储字符串本身

2. 在Java中“”引起来的也是String类型对象
那么这两种对象的存储方式有什么区别呢?
 
1c4580b6cc564e07b96a52f3b3b7382d.png
 

在s1使用常量串构造时,会直接在字符串常量池中创建字符串,在栈中直接存储字符串在字符串常量池中相应的位置

在s2通过new String对象的方式实例化字符串时,由于其字符串内容与s1一致,不会在常量池中创建新的对象,此时字符串对象存储在堆中,在堆中存储了对应字符在常量池中的位置

这样做有什么好处呢?就是所有的字符只用在字符串常量池中创建一次就行了,后续创建的相同的字符串只需引用对应的位置即可,大大提高了空间资源的利用效率

 

2、字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
 
1. String 类在设计时就是不可改变的, String 类实现描述中已经说明了
        以下来自JDK1.8中String类的部分实现:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];

可以看出:

1. String类被final修饰,表明该类不能被继承
2. value被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
 
2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

如在以下代码中:

String s1="hello";
String s2="hello";
s1="world";

5203648de539461c880b43d9a3c67fed.png

s1发生改变时,s2并不会改变指向,s1会重新分配内存地址进行赋值

String字符串具有不可变性,当字符串重新赋值时,不会在原来的内存地址进行修改,而是重新分配新的内存地址创建新的对象进行赋值

注意:

字符串不可变不是因为其内部保存字符的数组被final修饰了,因此不能改变。 不是因为String类自身,或者其内部value被final修饰而不能被修改。
final 修饰类表明该类不想被继承, final 修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内 容是可以修改的

 

3、字符串的比较

 

1. == 比较是否引用同一个对象
public static void main(String[] args) {
    int a = 10;
    int b = 20;
    int c = 10;

    // 对于基本类型变量,==比较两个变量中存储的值是否相同
    System.out.println(a == b); // false
    System.out.println(a == c); // true

    // 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("world");
    String s4 = s1;
    System.out.println(s1 == s2); // false
    System.out.println(s2 == s3); // false
    System.out.println(s1 == s4); // true
}
注意:对于内置类型,==比较的是变量中的值;对于引用类型==比较的是引用中的地址。
2. boolean equals(Object anObject) 方法:按照字典序比较
字典序:字符在ASCII码中的顺序
 
public boolean equals(Object anObject) {
    // 1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true
        if (this == anObject) {
            return true;
        }
    // 2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
        if (anObject instanceof String) {
    // 将anObject向下转型为String类型对象
            String anotherString = (String) anObject;
            int n = value.length;
    // 3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
    // 4. 按照字典序,从前往后逐个字符进行比较
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
    }

 

3、int compareTo(String s) 方法 : 按照字典序进行比较
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值

 

public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("abc");
    String s4 = new String("abcdef");

    System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
    System.out.println(s1.compareTo(s3)); // 相同输出 0
    System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}

 

4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较
 
public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("ABc");
    String s4 = new String("abcdef");

    System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1
    System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0
    System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同,输出长度差值 -3
}

4、 String的常用方法:

6beff4d7f2f04770946eefe5118cf518.png

 

 


 

二、StringBuider和StringBuffer

1、字符串的拼接

让我们先来看一下下面这个问题:

public static void main(String[] args) {
    String s1 = "abc";
    s1=s1+"def";
    
    System.out.println(s1); 
   
}
//以上代码创建了几个对象?

答案是三个

b8902bd75d364a9f878f3cc7fa22c3be.png

        首先语句“String s1 = new String("abc");”会在字符串中创建一个对象"abc",在执行语句"s1=s1+"def";"时,会先创建一个对象“def”,然后在创建两个对象相加后的结果“abcdef”

这时我们发现看似简单的一个拼接操作,竟然需要创建三个对象,其效率可想而知是非常低下的,因此我们在平时应用中一般会避免这样直接通过“+”进行字符串的拼接。那么我们该怎么去拼接呢?这时候我们就要介绍StringBuider和StringBuffer了

 

2、StringBuider与StringBuffer

        由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。他们的底层原理与String类似,都是通过数组来完成对字符串的存储,其默认长度为16,当实例化一个StringBuider对象时,会根据创建字符串的长度来初始化内存,数组的内存为“创建字符的长度+16”,即在进行修改字符串的操作时有16个字符的空间可供操作,在对字符串进行修改时,会自动检测当前char数组是否装的下,如果超出数组范围,会对char数组进行扩容。
 
扩容机制:创建一个新的char数组对象,其长度一般为原数组的两倍,接着判断是否足够存储新的字符串,如果不够再进行扩容,以此类推,直到创建的数组足够存储新的字符串为止。然后将新字符串的内容存储到新数组,最后将指针指向新的数组

常用方法:

e68bd5e063b241cb83c0df47881a7f84.png

 

String和StringBuilder最大的区别在于 String 的内容无法修改,而 StringBuilder 的内容可
以修改。频繁修改字符串的情况考虑使用StringBuilder
 
注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法
 
 
【面试题】String、StringBuffer、StringBuilder的区别
  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  • StringBuffer与StringBuilder大部分功能是相似的
  • StringBuffer大多数方法都使用了synchronized实现了同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

 

注意:在单线程的条件下,StringBuilder的运行效率要高于StringBuffer,因此在单线程的情况下一般选用StringBuilder,在多线程的情况下优先选用StringBuffer

 


总结

那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。作者还是一个萌新,如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊

b943785dc5844e63b6e407dfda9cc6e3.png

 

 
 
 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RIP协议(路由信息协议)

一、RIP协议概述 RIP协议&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;即根据跳数来度量路由开销&#xff0c;进行路由选择。 相比于其它路由协议&#xff08;如OSPF、ISIS等&#xff09;&#…

【Web】记录Polar靶场<中等>难度题一遍过(全)

目录 到底给不给flag呢 写shell 注入 某函数的复仇 xxe SSTI unpickle BlackMagic 反序列化 找找shell 再来ping一波啊 wu 代码审计1 你的马呢&#xff1f; ezphp 随机值 phpurl search file PlayGame csdn 反正持续一个月&#xff0c;感觉XYCTF…

MS SQL Server STUFF 函数实战 统计记录行转为列显示

目录 范例运行环境 视图样本设计 数据统计要求 STUFF函数实现 小结 范例运行环境 操作系统&#xff1a; Windows Server 2019 DataCenter 数据库&#xff1a;Microsoft SQL Server 2016 视图样本设计 假设某一视图 [v_pj_rep1_lname_score] 可查询对某一被评价人的绩效…

有单片机基础,准备过一遍freertos,之后再学linux

应届生我觉得继续把单片机深入一下比较好。 站在公司的角度思考一下&#xff0c;个人觉得应该有以下结论&#xff1a; 1 大公司具备技术资金等优势&#xff0c;因此喜欢学历好&#xff0c;理论扎实能够攻坚的人。倾向于培养各个领域的专家&#xff0c;共同构建自己产品的竞争…

网络安全之IP地址证书的重要性

在数字化时代&#xff0c;网络空间已成为各类活动的重要载体&#xff0c;无论是商业交易、信息交流还是远程办公&#xff0c;都离不开互联网的支撑。然而&#xff0c;网络环境的开放性与匿名性也带来了安全风险&#xff0c;如何确保网络交互中的身份真实可信&#xff0c;成为了…

C++中的面向对象到底是什么

C中的面向对象到底是什么 对象嘛&#xff0c;就和大家都有的对象一样&#xff0c;两只眼睛、一个嘴巴、两条腿…… 对不起跑题了&#xff0c;C的面向对象中的对象可不是显示中的对象哦&#xff0c;但是有一些相似之处&#xff0c;有对象的同学可以参考着去学习C面向对象的概念…

3. WiFi基本原理

1. WiFi简介 WiFi的全称是Wireless Fidelity。它是一种无线网络通信技术&#xff0c;由Wi-Fi联盟拥有&#xff0c;目的是改善基于IEEE 802.11标准的无线网络产品之间的互通性&#xff0c;允许电子设备在没有物理连接的情况下进行高速数据传输。此外&#xff0c;WiFi也被视为IE…

SpringCloudAlibaba服务消费者调用nacos服务报错:java.net.UnknownHostException: xxx

确保服务情况正常 通过服务名字调用(注意不需要添加端口号) RequestMapping("/add") public String add() {String url "http://stock-nacos/stock/reduce";String result restTemplate.getForObject(url, String.class);System.out.println("下单…

Vue性能优化--gZip

一、gZip简单介绍 1.1 什么是gzip gzip是GNUzip的缩写&#xff0c;最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术&#xff0c;web服务器和客户端&#xff08;浏览器&#xff09;必须共同支持gzip。目前主流的浏览器&#xff0c;Chro…

UE4 方块排序动画

【动画效果】 入动画&#xff1a; 出动画&#xff1a; 【分析】 入动画&#xff1a;方块动画排序方式为Z字形&#xff0c;堆砌方向为X和Y轴向 出动画&#xff1a;方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画

解锁AI提示工程新纪元:你的提问是关键!

文章目录 一、AI的潜力&#xff1a;无尽的宝藏等待解锁二、提问的艺术&#xff1a;挖掘AI潜力的关键三、AI的回应&#xff1a;超越预期的答案与启示四、提问的力量&#xff1a;推动AI不断进步与发展五、用提问开启与AI的智慧对话《向AI提问的艺术&#xff1a;提示工程入门与应用…

AdaBoost算法详解自用笔记(1)二分类问题举例分析

AdaBoost算法详解自用笔记&#xff08;1&#xff09;二分类问题举例分析 提升方法的思路 AdaBoost作为一种提升方法&#xff0c;其需要回答两个问题&#xff1a;一是每一轮如何改变训练数据的权重或概率分布&#xff1b;二是如何将弱分类器组合成一个强分类器。对于第一个问题…

【御控物联】JavaScript JSON结构转换(7):数组To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON数组 To JSON数组》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

《FDTD Solutions仿真全面教程:从基础入门到论文复现》

2024年5月11日-5月12日 2024年5月18日-5月19日 适用人群&#xff1a; 1.光电工程、物理学、材料科学等相关专业的硕博研究生及科研人员 2.工作于微纳光学、超构材料、光通信、光电子器件等领域的研发工程师 3.对光电仿真技术有浓厚兴趣且希望提升自身科研能力的高校教师和企业研…

ArcGIS操作(四)

任务&#xff1a; 根据江苏省夜间灯光影像完成数据处理与分析查阅统计年鉴数据以提取建成区空间分布位置完成建成区重心转移轨迹 步骤&#xff1a; 这里选取江苏省2000年、2004年、2008年夜光数据进行分析 加载影像 掩膜提取 投影 栅格转面 融合 栅格转面数据时分冗余&…

2024年,短期PMP备考上岸攻略!

今天分享一个PMP备考经验&#xff0c;正在备考PMP的小伙伴&#xff0c;咱们共勉&#xff01; 第一周、阅读教材 之前是第六版教材&#xff0c;花了很长时间阅读和梳理框架。现在是第七版教材&#xff0c;内容少了很多&#xff0c;只有300多页&#xff0c;不会特别耗时间&…

数据结构进阶篇 之 【堆的应用】(堆排序,TOP-K问题)详细讲解

所有人都关心我飞的高不高&#xff0c;只有我妈关心我翅膀硬不硬 一、堆的应用 1. 堆排序 1.1 建堆 1.2 利用堆删除思想来进行排序 2.TOP-K问题 二、完结撒❀ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–…

GPT-5:更强的ChatGPT!将在高级推理功能上实现重大进步!GPT-5有哪些功能作用?

自 Claude 3 发布以来&#xff0c;外界对 GPT-5 的期待越来越强。毕竟Claude 3已经全面超越了 GPT-4&#xff0c;成为迄今为止最强大模型。 对于即将发布的GPT-5&#xff0c;有哪些期待&#xff1f; 目前来说&#xff0c;GPT-5的将具备哪些新能力&#xff1f; GPT-5性能进步…

SA2601A 矽塔SYTATEK双NMOS半桥栅极驱动芯片 600V单相

SA2601A是一款针对于双NMOS的半桥栅极驱动芯片&#xff0c;专为高压、高速驱动N型功率MOSFET和IGBT设计&#xff0c;可在高达600V电压下工作。 SA2601A内置VCC和VBS欠压(UVLO)保护功能&#xff0c;防止功率管在过低的电压下工作&#xff0c;提高效率。 SA2601A输入脚兼容3.3-15…

安装pytorch3d 0.3.0遇到的一些问题

官网&#xff1a;PyTorch3D A library for deep learning with 3D datahttps://pytorch3d.org/最新版本pytorch3d/INSTALL.md at main facebookresearch/pytorch3d (github.com) 之前版本Releases facebookresearch/pytorch3d (github.com) 找到需要的版本&#xff0c;例如…