浅析 String

news2024/11/24 6:06:32

浅析String

  • 一、创建字符串
  • 二、字符串与常量池
  • 三、字符串的不可变性
  • 四、字符串的拼接
  • 五、StringBuilder和StringBuffer

一、创建字符串

    //三种常用的构造字符串的方式
    public static void main(String[] args) {
        String str1 = "hello";
        
        String str2 = new String("world");
        
        char[] chars = {'a','b','c'};
        String str3 = new String(chars);
    }

注意: String是引用类型,内部并不存储字符串本身。通过查看String类的实现源码可以发现,字符串实际由两部分value数组、hash值组成,字符串实际保存在char类型的数组中:

二、字符串与常量池

📝以下程序输出的结果是什么?在此过程中创建了几个String对象?

    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";

        String str3 = new String("Hello");
        System.out.println(str1==str2);
        System.out.println(str1==str3);
    }

分析: 双引号引起来的内容时存放在字符串常量池的,在直接赋值时,如果在字符串常量池中存在就直接返回常量池中字符串的引用,如果不存在则先在字符串常量池中创建一份。如果通过new创建字符串对象,同样会按照如上步骤检查常量池,只不过最后返回的是通过new创建的字符串对象。

最后我们说结论:此过程中str1会在常量池创建1个字符串对象,str2创建0个字符串对象,str3在堆区创建1字符串个对象。且str1==str2str1!=str3.

具体过程如下草图:

总结:

直接赋值产生10个字符串对象,使用newString()赋值时产生21字符串对象。赋值时先看字符串常量池,如果字符串常量池中没有,就在常量池中创建一个,如果有,前者直接赋值则直接引用,后者使用new String()在堆内存中还需创建一个实例对象(此时引用变量指向的是堆内存中创建的实例对象,而不是常量池中的实例对象)。

字符串常量池的作用:

“池” 是编程中的一种常见的, 重要的提升效率的方式。 对于字符串常量池来说,每次使用相同字面类型的常量时,Java会首先在字符串常量池中查找是否存在该常量的实例,如果存在则直接返回引用,避免重复创建新的实例,从而提高程序的运行速度并节省内存

三、字符串的不可变性

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

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

为什么 String 要设计成不可变的?

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

四、字符串的拼接

上面我们说String被设计成不可变类型,那么字符串的拼接该怎么解释呢?

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

我们将上面的代码进行编译,其实它的底层实现如下:

    public static void main4(String[] args) {
        //上述代码的底层实现:
        String str = "hello";

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.append("abc");
        str = stringBuilder.toString();

        System.out.println(str);
    }

所以,每次字符串的拼接底层都会创建一个StringBuilder对象,最后通过toString再返回一个新的String对象,可以想象如果在一个循环中使用字符串的拼接,那么它的效率将会非常低。话说回来,上面提到了StringBuilder,他究竟是什么?下面我们详细介绍:

五、StringBuilder和StringBuffer

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilderStringBuffer类。与String类的不同就是,在这些类中的对字符串修改的方法都是直接对原字符串进行修改,最后返回的都是修改后的原字符串。

此外,StringBuffer和StringBulider方法都是一样的,区别是StringBuffer被synchronized(锁)修饰,(线程安全)用在多线程情况下。单线程下一般用StringBuilder,因为频繁的加锁和释放锁也是需要耗费系统资源的。

(1)String、StringBuffer、StringBuilder的区别

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

(2)三者之间的转换

  1. StringBuffer或StringBuilder转String:调用toString方法
  2. String转StringBuffer或StringBuilder:利用它们的构造方法或append()方法

经典例题: 在不考虑常量池之前是否存在的情况下,以下总共创建了多少个String对象?

String str = new String("ab"); // 会创建多少个对象
String str = new String("a") + new String("b"); // 会创建多少个对象
//答案:2 5

解析:

对于代码 String str = new String(“ab”); 会创建两个String对象。首先,"ab"字面量会在字符串常量池中创建一个String对象,然后通过调用new String()构造函数创建第二个String对象。

对于代码 String str = new String(“a”) + new String(“b”); 会创建五个String对象。首先,字面量 “a” 和 “b” 分别会在字符串常量池中创建两个String对象。接着,通过 new String() 构造函数创建了另外两个String对象。最后,通过字符串拼接操作符 + 进行连接时,会创建一个新的String对象,其值为拼接结果 “ab”。

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

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

相关文章

Effective Java笔记(26)请不要使用原生态类型

首先介绍一些术语 。 声明中具有一个或者多个类型参数( type parameter )的类或者接口,就是泛型( generic )类或者接口 。 例如,List 接口就只有单个类型参数 E ,表示列表的元素类型 。这个接口…

码云 Gitee + Jenkins 配置教程

安装jdk 安装maven 安装Jenkins https://blog.csdn.net/minihuabei/article/details/132151292?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132151292%22%2C%22source%22%3A%22minihuabei%22%7D 插件安装 前往 Manage Jen…

聊聊汽车电子的话题

当谈到汽车电子时,有许多有趣的话题可以探讨。以下是一些可能感兴趣的话题: 自动驾驶技术:自动驾驶技术正变得越来越先进,它们如何在汽车中实现?它们将如何改变我们的交通方式以及对道路安全的影响? 电动汽…

【LeetCode每日一题】——85.最大矩形

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 困难 三【题目编号】 85.最大矩形 四【题目描述】 给定一个仅包含 0 …

【Java split】split() 函数分割空字符串后数组长度为1的原因以及规避措施(105)

问题现象: import java.util.ArrayList; import java.util.Arrays; import java.util.List;public class test06 {public static void main(String[] args) {// Java split()函数 分割空字符串长度为1的解释;String s2 "";String[] arr2 s2.split(&quo…

[SWPUCTF 2022 新生赛]numgame

这道题有点东西网页一段计算框,只有加和减数字,但是永远到大不了20,页面也没啥特别的,准备看源码,但是打不开,我以为是环境坏掉了,看wp别人也这样,只不过大佬的开发者工具可以打开&a…

elementUi select下拉框触底加载异步分页数据

在Element UI中,可以通过监听select下拉框的visible-change事件来实现触底加载下一页的效果。 方式一:利用elementUi的事件 具体步骤如下: 首先,在select组件中设置:visible-change"handleVisibleChange"…

Unity之获取用户地理位置

1.直接利用三方API获取&#xff1a; 1.1 利用bilibili的api 【未知稳定性】 public void Awake() {StartCoroutine(GetLocationInfoNew());}/// <summary>/// 利用bilibili的接口通过ip直接获取城市信息/// </summary>IEnumerator GetLocationInfoNew() {//UnityW…

在 Linux 上以 All-in-One 模式安装 KubeSphere

官方文档&#xff1a;https://www.kubesphere.io/zh/docs/v3.3/quick-start/all-in-one-on-linux/ 操作系统 最低配置 Ubuntu&#xff1a; 16.04,18.04, 20.04, 22.04 2 核 CPU&#xff0c;4 GB 内存&#xff0c;40 GB 磁盘空间Debian Buste&#xff1a;Stretch 2 核 CPU&am…

Leetcode周赛 | 2023-8-5

2023-8-5 题1体会我的代码 题2体会我的代码 题1 体会 一开始是觉得这道题是贪心的&#xff0c;选出现次数最多的元素&#xff0c;但是发现&#xff0c;当有多个元素出现次数均为最多时&#xff0c;似乎很难处理&#xff0c;就放弃了。转而问ChatGPT &#xff0c;结果让自己走上…

可视化高级绘图技巧100篇-总论

前言 优秀的数据可视化作品可以用三个关键词概括&#xff1a;准确、清晰、优雅。 准确&#xff1a;精准地反馈数据的特征信息&#xff08;既不遗漏也不冗余&#xff0c;不造成读者疏漏&误读细节&#xff09; 清晰&#xff1a;获取图表特征信息的时间越短越好 优雅&…

吃瓜教程-Task05

目录 支持向量机 间隔与支持向量 SVM基本型 对偶问题 kkt条件 例子 对偶问题 例子 对偶问题原理解释 软间隔与正则化 替代损失函数 支持向量回归 例子 支持向量机 间隔与支持向量 在样本空间中&#xff0c;划分超平面可通过如下线性方程来描述: 样本空间中任意点x到…

Doris(四)-聚合模型的使用

pre 前言 这里使用聚合模型&#xff0c;可以在导入数据的时候&#xff0c;就将部分数据做预处理&#xff0c;提高查询效率。 同样&#xff0c;因为是预处理&#xff0c;因此&#xff0c;数据细节会丢失。 1, 建表语句 create table if not exists user_landing_record_new …

基于Java+SpringBoot+Vue的篮球竞赛预约平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

框框大学之——教育技术学

清一色劝退的教育技术学。。。。。。 https://www.kkdaxue.com/?current1&major%E6%95%99%E8%82%B2%E6%8A%80%E6%9C%AF%E5%AD%A6&pageSize10&sortFieldcreateTime&sortOrderdescend 总结&#xff1a; 1 杂而不经 2 摆烂劝退居多 3 适合躺平 4 考公不行 5 要多…

探秘手机隐藏的望远镜功能:开启后,观察任何你想看的地方

当今的智能手机不仅仅是通信工具&#xff0c;它们蕴藏着各种隐藏的功能&#xff0c;其中之一就是让你拥有望远镜般的观察能力。是的&#xff0c;你没有听错&#xff01;今天我们将探秘手机中隐藏的望远镜功能&#xff0c;这项神奇的功能可以让你打开后&#xff0c;轻松观察任何…

L2CS-Net: 3D gaze estimation

L2CS-Net: Fine-Grained Gaze Estimation in Unconstrained Environments论文解析 摘要1. 简介2. Related Work3. METHOD3.1 Proposed loss function3.2 L2CS-Net 结构3.3 数据集3.4 评价指标 4. 实验4.1 实验结果 论文地址&#xff1a;L2CS-Net: Fine-Grained Gaze Estimation…

R语言安装包Seurat

环境Ubuntu22&#xff0c;R4.1 also installing the dependencies ‘curl’, ‘openssl’, ‘httr’, ‘plotly’ R包安装的时候报了这个错误ERROR: dependencies httr, plotly are not available for package Seurat 解决方法&#xff0c;退出R&#xff0c;在terminal中键入…

将整数,结构体,结构体数组,链表写到文件

在之前的学习中&#xff0c;忘文件中写的内容都是字符串或字符&#xff0c;本节学习如何写入其他各种类型的数据。 回看write和read函数的形式&#xff1a; ssize_t write(int fd, const void *buf, size_t count); ssize_t read(int fd, void *buf, size_t count); 其中&a…

(论文复现)DeepAnt模型复现及应用

DeepAnt论文如下&#xff0c;其主要是用于时间序列的无监督粗差探测。 其提出的模型架构如下&#xff1a; 该文提出了一个无监督的时间序列粗差探测模型&#xff0c;其主要有预测模块和探测模块组成&#xff0c;其中预测模块的网络结构如下。 预测结构是将时间序列数据组…