常用类(四)---String结构剖析

news2025/1/16 16:06:15

文章目录

  • 1.String结构剖析
  • 2.String创建剖析
  • 3.String特性分析
  • 4.String方法总结
  • 5.StringBuffer和StringBuilder总结
    • 5.1stringbuffer对象的创建方法
    • 5.2string--stringbuffer之间的相互转换:

这个是我第二次学习string,听的是hsp老师的课程,我认为有些东西可以速成,但是对于这个知识的学习,语法的学习,我们还是要听hsp这样的老师的课程,因为这个才是真正的学习,其他的一些机构都是浅尝辄止,我认为达不到学习的效果,所以听韩老师的课学第二遍;

1.String结构剖析

下面的这个常见对象的方式我们再熟悉不过了,但是我们真的未必理解他:

image-20241013193306968

image-20241013193649989

  1. 我们通过这个底层的源码可以看到:String这个类实际上是实现了三个接口的,分别是这个Serializable,Comparable,CharSequence接口,这个第一个表示这个string是可以进行串行化(这个表示String可以进行网络传输),我之前学习这个Mysql事务的时候听过这个名词。不了解也不要紧,我们后面还会学到的;
  2. Comparable这个接口表示我们的这个string对象之间其实是可以进行相互的比较的,这个是我们的string里面的一个进行比较的方法,我们后面也会遇到的;
  3. 在这个源码里面,我们可以看到这个string类的前面加上了这个final进行修饰,这个表示我们的string是不可以被继承,不可以修改的,这个不可以修改指的是我们的这个对象的引用指向的位置是不可以修改的,就是只能指向一块内存空间,不可以修改这个引用的指向,而不是不可以修改这个指向的内容,这个指向的内容是可以进行修改的;
  4. String里面实现了很多的构造器的重载,就是我们可以根据这个实际的需求去进行这个构造器的调用;
  5. 其实这个本质上是我们的这个string存放到了一个value数组里面,是这个数组的地址是确定的,不可以进行修改,这个才是科学的解释;

2.String创建剖析

String s1=“hspedu”;

String s2=new String(“hello”);

我们可以通过内存分布图,看一下两个创建对象方式的区别:

image-20241013200058340

我们使用第一个方式进行对象的创建的时候:是直接到我们的这个常量池里面去查看是否存在hspedu这个对象,如果有就会直接指向这个对象,如果没有,我们就会创建这个对象,然后再指向,这个时候栈区里面的这个s1指向的就是常量区里面的字符串,这个地址就是0x11;

第二个创建方式,我们的这个new是在堆区里面开辟空间,然后是到这个常量池里面去查看,这个字符串是不是存在,存在就直接指向这个字符串,否则就创建这个字符串,然后指向,因为我们的这个里面使用到的这个s1和s2是一样的,因此这个里面使用到的这个对象都是0x11这个内容,我们的这个堆区里面的这个value数组地址就是0x11,但是我们的这个堆区地址是0x22,我们的这个栈区上面的s2存放的是堆区的地址,因此,虽然两者指向的内容是一样的,但是这个时候两个引用的地址是有所差别的;


image-20241013201301594

上面的这个题目就是画出内存分布图,其实就很好的解决了:

image-20241013202359908

这个里面直接使用这个equals比较a,b的内容,这个肯定是一样的;

a==b比较的是两个引用的地址,这个时候一个存的是堆区的地址,一个是存放的这个常量区的地址,这个肯定是不一样的啦;

接下来用到了这个intern方法:可以发现,这个intern返回值就是我们的这个堆区指针指向的这个常量区内容的地址,因此这个a=b.intern()表示的就是我们的这个a引用的地址和我们的b在常量区的这个内容的地址进行比较,这个是一样的,也就是说,虽然我们的这个a=b不成立,但是我们的这个b.intern得到这个b常量池地址,这个就可以是一样的了;

最后一个是这个b.intern这个常量池的地址,b存的是我们的这个堆区上面的地址,因此这两个是不一样的,我们一定要理解这个每一个表示的方法,放的是哪个区域的地址,是堆区,还是常量池,我们的引用在哪里。我们的内容在哪里,这样我们就不会混乱了;

image-20241013202601342


image-20241013202141164

下面的这个就是这道题目的内存分布的情况:

首先这个p1.name和p2.name的内容进行比较,肯定是一样的;

p1.name和p2.name进行比较,这个比较的就是p1对象的这个name属性hspedu这个内容的地址,因此这个是没有问题的,两个的这个指向的是常量池上面的相同的区域,因此这个p1.name和p2.name就是一样的;

p1.name和我们的这个字符串进行比较,两个的地址也是一样的,因为这个p1.name就是我们的这个字符串,这个引用指向的是我们的这个常量池里面的这个内容的地址,我们的这个hspedu可以理解为一个字符数组,我们的这个就是打印字符数组的地址,这个字符数组的地址就是这个里面的第一个元素字符的地址,还是在这个常量池区域的这个字符串的地址,因此上面的这三个都是一样的;

下面的这个new出来的两个对象,不用看都是不一样,因为开辟的是堆区上面的不同的空间,我们的这个比较的就是堆区的地址,因此这个就是不一样的,如果是上面的s1.intern==s2.intern得到这个指向的常量池的地址,这个就是一样的;

image-20241013203741373


image-20241013200728547

我们上面的这个代码很简单,下面的这个就是一个简单的内存分布情况,因为这个里面没有涉及到我们的new的情况,这个没有显示出来堆区,我们的这两个对象都是在这个栈区上面的,字符串内容是在我们的常量区,因为两个内容是完全一样的,因此这个时候栈区的引用指向的空间是一样的,无论是equals进行内容比较,还是这个==进行这个内存地址的比较,两个都是一样的;

image-20241013200910006

3.String特性分析

image-20241013210715834

这个其实进行的就是我们的编译器的优化,实际上就创建了一个对象,而不是三个对象;


image-20241013210755396

这个a+b并不是和上面的内容相加一样,这个时候是进行了多于操作的:

首先我们的这个a+b的时候会创建一个stringBuilder的对象,然后使用这个append方法,把我们的这个字符串的内容添加到这个对象里面去,最后使用这个toString方法,把这个对象转换为我们的string类型的作为返回值

我们的这个c就会指向这个堆区上面的对象,这个对象的内容是在我们的常量池上面的,因此这个a+b操作涉及到了new操作,这个就和我们的堆区有关,这个时候的c指向的就是我们的堆区上面的地址;

image-20241013213239260


image-20241013212010112

上面的这个也是韩老师上课用到的一个案例,我之前的一个博客里面已经介绍了这个,就是我们额str=java是指向了新的对象,这个指向的是新的空间,ch[0]表示的就是对于我们原来的内容进行修改;

这个里面调用到了这个change方法,这个调用方法就会创建新的栈,就是在这个栈上面开辟新的空间,这个时候我们的原来的栈和新的栈上面都有这个str,这个时候指向的是相同的空间,在这个change方法里面,我们让这个形参栈的str指向新的str,而且修改这个ch数组里面的内容,然后这个新参的栈就小销毁了;

我们打印的时候,ex.str是这个实参的str内容,因此这个还是打印的hsp,但是这个ch被我们的形参修改了,虽然形参的栈销毁了,但是这个修改保留了下来,因此这个数组的打印结果就是hava;

想要更加深入了解的小伙伴可以去看我的主页的文章—函数栈帧的创建和销毁,明白这个过程,这个题目的栈帧的销毁创建就不难理解了;我们的形参的这个栈开始的时候指向的内容和我们的实参是一样的,但是我们的str是指向了新的内容,ch是修改元素的内容;

4.String方法总结

这个里面其实是有很多的方法的,但是之前已经总结过一些:这个里面就写一个之前没有遇到过的方法

compareto方法进行字符串的比较:

String str1="jcck";
String str2="jack";
System.out.println(a.compareTo(str2));

上面的这个情形下,这个str1和str2两个对象的这个长度是一样的,我们就会从前面开始比较,这个第一个字符一样,开始比较第二个字符,c的这个码值比a大二,这个时候的返回值就是我们的2;

如果两个字符串的长度不一样:

String str1="jcc";
String str2="jack";
System.out.println(a.compareTo(str2));

其实这个情况下,我们就会使用第一个字符串的长度减去第二个字符串的长度,因此这个时候的返回值就是我们的3-4=-1;

即长度相等的时候返回值是我们的码值的差值,长度不相等的时候返回的是我们的字符串的长度的差值;

方法了解就可以了,我们用到的时候到这个文档里面查找即可;

5.StringBuffer和StringBuilder总结

5.1stringbuffer对象的创建方法

string每一次变化都需要在这个常量池里面创建新的对象,但是我们的这个stringbuilder是在我们的堆区的,因为这个stringbuilder内容是可以修改的,不是在常量区,而是在这个堆区上面的;—stringbuilder效率会更高

下面的是stringbuffer对象三个不同的创建方式:

第一个没有任何的参数,这个时候就是开辟出来大小为16的数组空间;

制定了一个数字参数,就会开辟出来该容量大小的空间;

指定了一个字符串,我们开辟空间的大小就是这个字符串的长度加上16;

image-20241014210933301


5.2string–stringbuffer之间的相互转换:

string转换为stringbuffer:

下面的两个方式:一个是直接把我们的这个str作为参数,第二个就是调用这个append方法,把我们的这个字符串添加到这个对象里面去,这个时候相当于是创建了一个内容一样的stringbuffer对象;

image-20241014211543694

stringbuffer转换为string对象:

一种就是使用我们的这个tostring方法进行这个转换;

第二个就是使用new一个string对象,这个里面的参数就是我们的这个stringbuffer对象;

image-20241014211855881

stringbuiler主要是单线程的情况,因为这个本身是不安全的,但是对于这个单线程的情况,速度是比这个stringbuffer更快的;

image-20241014212706128
buffer对象;

[外链图片转存中…(img-KheAQLSp-1728912498496)]

stringbuiler主要是单线程的情况,因为这个本身是不安全的,但是对于这个单线程的情况,速度是比这个stringbuffer更快的;

[外链图片转存中…(img-iiA9ihRj-1728912498497)]

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

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

相关文章

IRP读写函数

驱动代码&#xff1a; #include <ntddk.h>#define DEVICE_NAME L"\\device\\MyDricer1" //设备对象名称 #define LINK_NAME L"\\dosdevices\\Goose" //符号链接名称VOID UnDirver(PDRIVER_OBJECT pDriverObj) {UNICODE_STRING uLinkName RTL_CONST…

OpenCV高级图形用户界面(6)获取指定窗口中图像的矩形区域函数getWindowImageRect()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 提供窗口中图像的矩形区域。 该函数 getWindowImageRect 返回图像渲染区域的客户端屏幕坐标、宽度和高度。 函数原型 Rect cv::getWindowImage…

旺店通ERP集成金蝶云星瀚(旺店通主供应链)

源系统成集云目标系统 金蝶云星瀚介绍 金蝶云星瀚是专为大企业设计的新一代数字化管理云服务、大型企业SaaS管理云&#xff0c;旨在凭借千亿级高性能和世界一流企业的实践&#xff0c;帮助大企业实现可信的数字化系统升迁&#xff0c;打造韧性企业&#xff0c;支撑商业创新和管…

C++:list(用法篇+模拟实现)

文章目录 前言一、list 的用法1. list 简介2. 用法代码演示1&#xff09;头/尾 插/删和迭代器遍历2&#xff09;insert与erase3&#xff09;排序sort相关4&#xff09;其他相关 二、list模拟实现1. 结点类模板list_node2. 定义迭代器1&#xff09;为什么要专门封装一个迭代器&a…

【uniapp】设置公共样式,实现公共背景等

目录 1、 全局渐变背景色 2.1 创建common目录 2.2 在common下新建style和images等目录 2.3 在style下新建common-style.scss 2.4 common-style输入全局渐变颜色 2.5 引入样式 2.6 业务页面引入 2.7 展示 2、全局字体颜色 2.1 新建base-style.scss文件 2.2 设置base-…

STM32的GPIO寄存器描述

寄存器&#xff1a; 软件控制硬件(在程序中操作对应控制器)&#xff0c;通过寄存器&#xff0c;就是 寄存器(可以存放数据)&#xff0c;但是其中的数据具有特定的硬件含义(查看芯片手册)&#xff0c;设置寄存器的值&#xff0c;对应的控制器就执行对应的工作。相当于寄存器就是…

IntelliJ IDEA中配置scala

1.IDEA中 配置 maven 左上角 file -> Setting 选择(或直接搜maven) Build, Execution,Deployment -> Build Toos -> Maven Maven home path 选择 maven 安装目录&#xff08;bin的上层目录&#xff09; 示例&#xff1a; D:\maven\apache-maven-3.8.6 User settings…

2024.10月11日--- SpringMVC拦截器

拦截器 1 回顾过滤器&#xff1a; Servlet规范中的三大接口&#xff1a;Servlet接口&#xff0c;Filter接口、Listener接口。 过滤器接口&#xff0c;是Servlet2.3版本以来&#xff0c;定义的一种小型的&#xff0c;可插拔的Web组件&#xff0c;可以用来拦截和处理Servlet容…

基于Springboot+Vue的租房管理系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统根…

yjs机器学习常见算法01——KNN(K—近邻算法)

1.K—近邻算法 的含义&#xff1a; 简单来说就是通过你的邻居的“类别”&#xff0c;来推测你的“类别” 定义&#xff1a;如果一个样本在特征空间中的k个最相似&#xff08;即特征空间中最临近&#xff09;的样本中大多数属于某一类别&#xff0c;则该样本也属于这个类别。 2.…

Linux系统:本机(物理主机)访问不了虚拟机中的apache服务问题的解决方案

学习目标&#xff1a; 提示&#xff1a;本文主要讲述-本机(物理主机)访问不了虚拟机中的apache服务情况下的解决方案 Linux系统&#xff1a;Ubuntu 23.04&#xff1b; 文中提到的“本机”&#xff1a;代表&#xff0c;宿主机&#xff0c;物理主机&#xff1b; 首先&#xff0c…

SAM 2视觉大模型:图像和视频一键抠图,本地部署整合包

在人工智能和计算机视觉领域&#xff0c;图像和视频的分割技术一直是研究的热点。最近&#xff0c;Meta公司&#xff08;原Facebook&#xff09;推出了一款名为Segment Anything Model 2&#xff08;简称SAM 2&#xff09;的新型AI模型&#xff0c;它在图像和视频分割领域取得了…

layui table 自定义表头

自定义表头-查询 js/css静态文件引用 <!-- 引入 layui.css --> <link href"//unpkg.com/layui2.9.16/dist/css/layui.css" rel"stylesheet"> <!-- 引入 layui.js --> <script src"//unpkg.com/layui2.9.16/dist/layui.js"…

【C++打怪之路Lv9】-- vector

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

Flink系统架构和应用部署方式

目录 概述 Flink集群架构组件 Client JobManager TaskManagers 算子、Task和Subtask三者关系 概念 算子和Task的关系 Task和SubTask的关系 算子和SubTask的关系 样例 Task Slots和资源的关系 Flink应用程序部署 Flink Session 集群 Flink Job 集群 Flink Appli…

「Java服务」快速接入SkyWalking方法指南

一、背景 背景&#xff1a;Apache SkyWalking 是一个开源的分布式应用性能监控&#xff08;APM&#xff09;系统&#xff0c;主要用于监控微服务、云原生和容器化应用的性能。接入SkyWalking可以排查以智能投放服务为主的服务响应问题 技术架构 SkyWalking 的核心架构包括以…

[含文档+PPT+源码等]精品基于ssm实现的原生微信小程序线上养花系统的设计与实现

基于SSM&#xff08;Spring、SpringMVC、MyBatis&#xff09;实现的原生微信小程序线上养花系统的设计与实现背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、选题背景 随着人们生活水平的提高和环境保护意识的增强&#xff0c;养花已经成为一种流行的休闲活动。…

UE5 猎户座漂浮小岛 04 声音 材质

UE5 猎户座漂浮小岛 04 声音 材质 1.声音 1.1 导入 wav格式 1.2 循环播放 1.3 mp3转wav 1.4 新手包素材&#xff08;火焰 &#xff09; particle&#xff1a;颗粒 2.材质 2.1 基本颜色 M_Yellow 2.2 混合模式与双面材质 2.3 金属感、高光、粗糙度 M_AluminumAlloy 2.4 自…

【JAVA毕业设计】基于Vue和SpringBoot的课程管理平台

本文项目编号 T 006 &#xff0c;文末自助获取源码 \color{red}{T006&#xff0c;文末自助获取源码} T006&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 数据库设计 六、…