当前位置: 首页 > news >正文

String 进阶

字符串拼接

// 常量与常量的拼接结果放在常量池
// 常量池中不会存在相同的常量
String str1 = "a" + "b";
System.out.println(str1 == "ab");
// 拼接时有一个为变量,则结果会放在堆中。
// 变量拼接的原理是 StringBuilder append 最后toString 
// 查看字节码指令就可以看到详细过程
// 就是在堆空间中 new String
String a = "a";
String str2 = a + "b";
System.out.println(str2 == "ab");
// 拼接结果调用 intern 方法,则主动将常量池中还没有的字符串对象放入字符串常量池,并返回对应地址
// 如果常量池中有对应字符串对象,则返回已有的字符串对象地址
String b = "b";
String str3 = ("a" + b).intern();
System.out.println(str3 == "ab");
// final 修饰的变量,在编译时就会进行赋值确定
String str4 = a + b;
System.out.println(str4 == "ab");// false
final String c = "c";
final String d = "d";
String str5 = c + d;
System.out.println(str5 == "cd");// true

使用 StringBulider 进行拼接

int i = 0;
String str = "";
while (i < 1000){str += "a";
}

循环中每次 str + “a” 都会创建一个 StringBuilder ,然后toString。效率极低。

int i = 0;
StringBuilder sb = new StringBuilder();
while (i < 1000){sb.append("a");
}
String str = sb.toString();

只 new 了一个StringBuilder,且只 toString 一次。

进一步优化

int i = 0;
StringBuilder sb = new StringBuilder(1000);
while (i < 1000){sb.append("a");
}
String str = sb.toString();

优化方式和ArrayList一样。如果我们能大概确定要生成的字符串长度,我们可以初始化 StringBuilder 的底层 char[] 数组的长度,避免超过长度时的扩容操作。

new String 会创建几个对象?

String s = new String(“ab”) 会创建两个对象。一个在堆空间,一个在字符串常量池。此时 s 的地址为指向堆空间的字符串对象。

具体可以在 idea 中下载 jclasslib 插件,查看字节码的方式来解释
在这里插入图片描述

引申

new String("a") + new String("b") // 创建了几个对象?
1. new String("a") 创建两个对象,堆和常量池
2. new String("b") 创建两个对象,堆和常量池
3. 两个非常量相加,会创建一个 StringBuilder 对象使用其 append 方法,最后 toString
4. toString 方法会 new 一个 String 对象(但其不会在常量池生成对象"ab"

intern 方法的使用

public native String intern();

intern 是一个 native 方法,如果当前常量池没有当前字符串对应相等(equals 为 true)的字符串,则将对象放入字符串常量池,并返回对应地址。如果常量池中有对应字符串对象,则返回已有的字符串对象地址

示例

String a = new String("a");
a.intern();
System.out.println(a == "a"); //jdk6 false jdk1.7+ falseString b = new String("b") + new String("b");
b.intern();
System.out.println(b == "bb");//jdk6 false jdk1.7+ true

对象 a 指向的时堆中的字符串对象地址,“a” 放在常量池的,所以为 false

new String(“b”) + new String(“b”) 不会在常量池创建对象 “ab”,其主要问题是,jdk1.7+ 环境中,在调用 intern 方法的时候,不是在常量池中创建一个新的对象 “ab”,而是将当前堆中 new 的 “ab” 的引用赋值给了常量池的引用,导致堆和常量池中的引用都指向了同一个地址。基于此特性,下面的示例结果就能够解释了。

String c = new String("c") + new String("c");
String cc = "cc";
c.intern(); // 当前 "cc" 在常量池已经存在,且和堆中的对象引用不同
System.out.println(c == cc);// jdk1.7+ falseString d = new String("d") + new String("d");
d.intern();// 此时 "dd" 在常量池还不存在,基于上面的解释,此时堆和常量池中的"dd"对象的引用是一致的
String dd = "dd";
System.out.println(d == dd);//  jdk1.7+  true

intern 使用技巧

大量的 String 对象使用的时候,比如:String 数组或大的集合中存放 String 对象,可以对String对象先调用 intern 方法返回常量池引用后存放。这样的好处是,最后这些大量的引用都引用的常量池的对象,堆中的对象可以正常 GC 释放。此方式特别在有大量重复字符串对象的时候能节省大量的空间。

相关文章:

String 进阶

字符串拼接 // 常量与常量的拼接结果放在常量池 // 常量池中不会存在相同的常量 String str1 "a" "b"; System.out.println(str1 "ab");// 拼接时有一个为变量&#xff0c;则结果会放在堆中。 // 变量拼接的原理是 StringBuilder append 最后…...

ESP32设备通信-两个ESP32间UART通信

两个ESP32间UART通信 文章目录 两个ESP32间UART通信1、UART介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将使用 Arduino IDE 的 UART 硬件库在两个 ESP32 板之间执行 UART 或串行通信。 要使用 USB 端口调试和编程 ESP32,需要使用称为通用异步接收器/发送器 (UART) 通…...

LCR 052.递增顺序搜索树

​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 052. 递增顺序搜索树 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 中序遍历时修改指针即可。 解题代码&#xff1a; /*** Definition for a binary tree node.* public class TreeNo…...

Mysql集群技术问答

前提&#xff1a;Mysql集群服务部署到一个群组的所有服务器上&#xff0c;一般20台为一个群组&#xff0c;群组内所有节点数据实时同步&#xff0c;动态自动维护节点。 问&#xff1a;集群空间跟传统空间的最大不同是什么&#xff1f; 答&#xff1a;集群空间有数据同步和宕机检…...

2023版 STM32实战4 滴答定时器精准延时

SysTick简介与特性 -1- SysTick属于系统时钟。 -2- SysTick定时器被捆绑在NVIC中。 -3- SysTick可以产生中断,且中断不可屏蔽。 SysTick的时钟源查看 通过时钟树可以看出滴答的时钟最大为72MHZ/89MHZ 通过中文参考手册也可以得到这个结论 代码编写&#xff08;已经验证&a…...

ESP32设备驱动-数据持久化到Flash

数据持久化到Flash 文章目录 数据持久化到Flash1、Preferences库介绍2、软件准备3、硬件准备4、代码实现4.1 初始化NVS Flash4.2 读写Key/Value对4.3 保存/读取网络凭据4.4 复位后记住最后的 GPIO 状态在本文中,我们将介绍如何使用 Preferences库将数据存储到 ESP32 的Flash中…...

Swift data范围截取问题

文章目录 一、截取字符串的几种方法1. 截取前几位2. 截取后几位3. subData4. 下标截取 二、subData(in:) 报错 EXC_BREAKPOINT 一、截取字符串的几种方法 1. 截取前几位 mobileID.prefix(32)2. 截取后几位 mobileID.suffix(3)3. subData data.subdata(in: 0..<4)4. 下标…...

PICO首届XR开发者挑战赛正式启动,助推行业迈入“VR+MR”新阶段

9月25日&#xff0c;“PICO 2023首届XR开发者挑战赛”&#xff08;下文简称“挑战赛”&#xff09;媒体启动会在北京圆满落幕&#xff0c;官方赛事报名通道已于今日开启。据悉&#xff0c;本次挑战赛是PICO首次针对全球开发者举办的大型挑战赛事&#xff0c;旨在与开发者保持连…...

【计算机网络】应用层协议原理

文章目录 网络应用程序体系结构客户-服务器体系结构P2P体系结构 进程通信客户和服务器进程进程与计算机网络之间的接口进程寻址 可供应用程序使用的运输服务可靠数据传输吞吐量定时安全性 因特网提供的运输服务TCP服务面向连接的服务可靠数据传输服务TCP安全 UDP服务因特网运输…...

buuctf-[WUSTCTF2020]CV Maker

打开环境 随便登录注册一下 进入到了profile.php 其他没有什么页面&#xff0c;只能更换头像上传文件&#xff0c;所以猜测是文件上传漏洞 上传一句话木马看看 <?php eval($_POST[a]);?>回显 搜索一下 添加文件头GIF89a。上传php文件 查看页面源代码&#xff0c;看…...

数据库表操作详解

在数据库管理中,表操作是最基础也最常用的一项功能。不论是临时存储一些数据,还是通过派生表进行复杂的查询,表操作的灵活性和多样性都使其在数据库中发挥着重要的作用。 本文将详细解析数据库中常见的表操作,包括临时表、派生表以及与视图、子查询的比较。我们将使用游戏…...

axios配置代理ip

axios配置代理ip 对于在nodejs中使用axios作为请求库时&#xff0c;有需要配置代理ip的需求&#xff08;比如爬虫等等&#xff09; 最离谱的是&#xff0c;在网上搜了一圈&#xff0c;全是关于axios配置proxy跨域的解决办法&#xff0c;没有配置代理ip的方法。 const axios …...

Apache Commons Pool2 池化技术

对象池是一种设计模式&#xff0c;用于管理和重用对象&#xff0c;以提高性能和资源利用率。对象池的概念在许多应用程序中都有广泛应用&#xff0c;特别是在需要频繁创建和销毁对象的情况下&#xff0c;例如数据库连接、线程、HTTP连接等 对象池通过预先创建一组对象并将它们存…...

二叉树的最近公共祖先LCA

系列题目 236. 二叉树的最近公共祖先 1676. 二叉树的最近公共祖先IV 1644. 二叉树的最近公共祖先 II 235. 二叉搜索树的最近公共祖先 1650. 二叉树的最近公共祖先 III class LowestCommonAncestor:"""236. 二叉树的最近公共祖先题目强调p和q一定存在于二叉树中&…...

AWS SAA知识点整理(作成中)

共通 一些信息已经更新了&#xff0c;但参考题的答案还是旧的。 比如&#xff1a; S3的最大读写性能已经提高到 3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second 并且不再要求使用random prefix 题目中有时候会让选择Not violation 不合适的一项&#xff…...

C++模板大全(持续更新,依不同网站整理而成)

C模板大全 基本模板快读快写快读快写火车头缺省源 基本算法暴力枚举模拟贪心二分三分尺取法分治前缀和差分递推递归倍增排序sort冒泡排序桶排序选择排序插入排序希尔排序归并排序快速排序堆排序计数排序基数排序 基础数据结构栈队列哈希链表单向链表双向链表 单调栈单调队列 高…...

《CTFshow-Web入门》10. Web 91~110

Web 入门 索引web91题解总结 web92题解总结 web93题解 web94题解 web95题解 web96题解 web97题解 web98题解 web99题解总结 web100题解 web101题解 web102题解 web103题解 web104题解 web105题解总结 web106题解 web107题解 web108题解 web109题解 web110题解 ctf - web入门 索…...

计组--总线

一、概念 总线是一组能为多个部件分时共享的公共信息传送线路。 共享是指总线上可以挂接多个部件&#xff0c;各个部件之间互相交换的信息都可以通过这组线路分时共享。 分时是指同一时刻只允许有一个部件向总线发送信息&#xff0c;如果系统中有多个部件&#xff0c;则它们…...

Git中的HEAD

Git中的HEAD HEAD^数字&#xff1a;表示当前提交的父提交&#xff0c;具体是第几个父提交通过数字指定&#xff0c;HEAD^1第一个父提交&#xff0c;该语法只 能用于合并(merge)的提交记录&#xff0c;因为一个通过合并产生的commit对象才有多个父提交。 HEAD~数字&#xff1…...

软件设计师_数据库系统_学习笔记

文章目录 3.1 数据库模式3.1.1 三级模式 两级映射3.1.2 数据库设计过程 3.2 ER模型3.3 关系代数与元组演算3.4 规范化理论3.5 并发控制3.6 数据库完整性约束3.7 分布式数据库3.8 数据仓库与数据挖掘 3.1 数据库模式 3.1.1 三级模式 两级映射 内模式直接与物理数据库相关联的 定…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...