Java基础-String Class(字符串类)
String
Java String 类概览
String 类是 Java 中最常用的类之一,用于处理字符串。以下是 String 类的主要特性和操作:
| 特性/操作 | 描述 |
|---|---|
| 不可变性 | String 对象一旦创建就不能被修改 |
| 创建方式 | 使用双引号 “” 或 String 构造函数 |
| 字符串池 | Java 维护字符串常量池以优化内存使用 |
| 比较操作 | equals() 比较内容,compareTo() 比较顺序 |
| 连接操作 | 使用 + 运算符或 concat() 方法 |
String的常用Method
| 方法 | 描述 | 示例 |
|---|---|---|
length() | 返回字符串的长度 | "Hello".length()返回 5 |
charAt(int index) | 返回指定索引处的字符 | "Java".charAt(0)返回 ‘J’ |
substring(int beginIndex, int endIndex) | 返回一个新的字符串,它是此字符串的一个子字符串 | "Hello".substring(0, 3)返回 “Hel” |
equals(Object anObject) | 将此字符串与指定的对象比较 | "Hello".equals("Hello")返回 true |
toLowerCase() | 使用默认语言环境的规则将此 String 中的所有字符都转换为小写 | "HELLO".toLowerCase()返回 “hello” |
toUpperCase() | 使用默认语言环境的规则将此 String 中的所有字符都转换为大写 | "hello".toUpperCase()返回 “HELLO” |
trim() | 返回字符串的副本,忽略前导空白和尾部空白 | " hello ".trim()返回 “hello” |
replace(char oldChar, char newChar) | 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的 | "hello".replace('l', 'w')返回 “hewwo” |
contains(CharSequence s) | 当且仅当此字符串包含指定的 char 值序列时,返回 true | "Hello".contains("He")返回 true |
split(String regex) | 根据给定正则表达式的匹配拆分此字符串 | "a,b,c".split(",")返回 [“a”, “b”, “c”] |
下面的流程图展示了 String 对象的生命周期和常见操作:
这个流程图说明了 String 对象从创建到使用的过程,包括字符串池的检查、字符串操作和不可变性原则。理解这个过程有助于更高效地使用 String 类。
Stirng的继承关系
在 Java 中,String类最终继承自java.lang.Object类,并且它实现了java.io.Serializable、java.lang.Comparable<String>和java.lang.CharSequence接口。以下是用 Mermaid 语法展示的更详细的关系图:
说明如下:
Object类:
- 所有 Java 对象的根类,
String继承了Object的一些通用方法,如toString()、equals()和hashCode()等。
Serializable接口:
- 标记接口,表示一个类的对象可以被序列化和反序列化。
String类的对象可以被写入到输出流并从输入流中读取,从而实现序列化和反序列化操作。
Comparable<String>接口:
- 定义了一个类型参数为
String的泛型接口,用于定义对象之间的自然顺序。String类实现了这个接口,意味着可以比较两个字符串的字典顺序。通过compareTo方法可以比较两个字符串的大小关系。
CharSequence接口:
- 表示一个字符序列。
String类实现了这个接口,提供了一些方法来访问字符串中的字符,如length()返回字符串的长度,charAt(int index)返回指定索引处的字符,subSequence(int start, int end)返回一个子序列。
缺点
由于String的不可变性,在进行大量字符串操作时可能会创建很多中间对象,这可能会影响性能。为了避免这种情况,可以使用StringBuilder或StringBuffer类,它们是可变的字符串类,适用于频繁修改字符串的场景。
字符串的特性
字符串的连接
- 字符串连接:
String c = a + b进行字符串连接操作。在 Java 中,使用+运算符连接两个字符串时,实际上会创建一个新的String对象。- 这个过程中,Java 会先创建一个
StringBuilder(或StringBuffer,在单线程环境下通常是StringBuilder)对象,然后调用append方法将a和b的内容添加到StringBuilder中,最后调用toString方法将StringBuilder转换为String对象,并将其赋值给c。
String a = "abc";
String b = "MASU";
String c = a + b;
System.out.println(c); // 输出 "abcMASU"
注意事项
频繁进行字符串连接操作可能会在性能上产生一些开销,特别是在循环中进行大量的字符串连接时。因为每次连接都会创建新的 StringBuilder 和 String 对象。在这种情况下,可以考虑使用 StringBuilder 或 StringBuffer 显式地进行字符串连接操作,以提高性能。
StringBuilder builder = new StringBuilder();
builder.append("abc");
builder.append("MASU");
String c = builder.toString();
StringBuffer
基本介绍
StringBuffer是 Java 中用于处理可变字符串的类。与String类不同,String对象是不可变的.StringBuffer允许对字符串进行修改,例如添加、插入、删除字符等操作,且不会产生新的对象(除非重新赋值)。这在需要频繁修改字符串内容的场景中非常有用,能够避免创建大量中间字符串对象,从而提高性能。
StringBuffer 的继承结构图

- 常用方法
- 追加(append)方法
append方法用于在StringBuffer对象的末尾添加各种类型的数据,如字符、字符串、数字等。例如:
- 追加(append)方法
StringBuffer sb = new StringBuffer("Hello");sb.append(" World");System.out.println(sb.toString());//输出"Hello World"
- 它有多个重载版本,可以接受
char、int、long、float、double、boolean、char[]、String等多种类型的参数。 - 插入(insert)方法
- 用于在
StringBuffer对象的指定位置插入各种类型的数据。例如:
- 用于在
StringBuffer sb = new StringBuffer("Hello");sb.insert(2, "inserted");System.out.println(sb.toString());//输出"Heinsertedllo"
-
它的第一个参数是插入的位置索引(从 0 开始),第二个参数是要插入的内容,同样有多个重载版本,可插入不同类型的数据。
-
删除(delete)方法
-
可以删除
StringBuffer对象中指定位置的字符。例如:StringBuffer sb = new StringBuffer("Hello");sb.delete(1, 3);System.out.println(sb.toString());//输出"Hlo"
-
-
其参数
delete(start, end)表示删除从start(包含)到end(不包含)位置的字符。 -
替换(replace)方法
- 用于替换
StringBuffer对象中指定位置的字符。例如:
- 用于替换
StringBuffer sb = new StringBuffer("Hello");sb.replace(1, 3, "replaced");System.out.println(sb.toString());//输出"Hreplacedlo"
- 它的参数
replace(start, end, str)表示将从start(包含)到end(不包含)位置的字符替换为str。 - 反转(reverse)方法
- 可以将
StringBuffer对象中的字符序列反转。例如:
- 可以将
StringBuffer sb = new StringBuffer("Hello");sb.reverse();System.out.println(sb.toString());//输出"olleH"
- 与 StringBuilder 的比较
StringBuilder和StringBuffer功能相似,都用于可变字符串的操作。主要区别在于StringBuffer是线程安全的,其内部方法大多是synchronized(同步)的,这使得它在多线程环境下能够正确运行,但性能上会有一定损耗。而StringBuilder不是线程安全的,在单线程环境下性能更好,通常在不需要考虑线程安全的情况下,推荐使用StringBuilder。
- 容量管理
StringBuffer对象有一个容量(capacity)的概念,它表示StringBuffer内部用于存储字符序列的缓冲区大小。当向StringBuffer中添加字符,导致字符序列长度超过当前容量时,StringBuffer会自动扩容。- 扩容的策略一般是:
新容量 = 旧容量 * 2 + 2。例如,初始容量为 16,当字符序列长度超过 16 时,新容量可能会变为16*2 + 2=34。可以通过capacity方法查看当前容量,如System.out.println(sb.capacity());。
StringBuffer常用方法
| 方法名 | 介绍 | 示例 |
|---|---|---|
append(Object obj) | 将指定对象的字符串表示形式追加到当前StringBuffer对象的末尾。可以接收多种数据类型,如String、char、int、double等 | StringBuffer sb = new StringBuffer("abc"); sb.append("def"); // sb的值变为"abcdef" |
insert(int offset, Object obj) | 在当前StringBuffer对象的指定位置(offset)插入指定对象的字符串表示形式。offset表示索引位置,从 0 开始计数 | StringBuffer sb = new StringBuffer("abc"); sb.insert(1, "x"); // sb的值变为"axbc" |
delete(int start, int end) | 删除当前StringBuffer对象中从start(包括)到end(不包括)之间的字符 | StringBuffer sb = new StringBuffer("abcde"); sb.delete(1, 3); // sb的值变为"ade" |
replace(int start, int end, String str) | 将当前StringBuffer对象中从start(包括)到end(不包括)之间的字符替换为指定的字符串str | StringBuffer sb = new StringBuffer("abcde"); sb.replace(1, 3, "xx"); // sb的值变为"axxde" |
reverse() | 反转当前StringBuffer对象中的字符序列 | StringBuffer sb = new StringBuffer("abc"); sb.reverse(); // sb的值变为"cba" |
substring(int start) | 返回一个新的String,它包含当前StringBuffer对象从start位置到末尾的字符序列 | StringBuffer sb = new StringBuffer("abcde"); String sub = sb.substring(2); // sub的值为"cde" |
substring(int start, int end) | 返回一个新的String,它包含当前StringBuffer对象从start(包括)到end(不包括)之间的字符序列 | StringBuffer sb = new StringBuffer("abcde"); String sub = sb.substring(1, 3); // sub的值为"bc" |
capacity() | 返回当前StringBuffer对象的容量。容量是指用于存储字符序列的内部缓冲区大小,一般初始容量为 16,当内容超过容量时会自动扩容 | StringBuffer sb = new StringBuffer("abc"); System.out.println(sb.capacity()); // 可能输出16 |
length() | 返回当前StringBuffer对象中字符序列的长度 | StringBuffer sb = new StringBuffer("abc"); System.out.println(sb.length()); // 输出3 |
setCharAt(int index, char ch) | 将当前StringBuffer对象中指定索引(index)位置的字符设置为ch | StringBuffer sb = new StringBuffer("abc"); sb.setCharAt(1, 'x'); // sb的值变为"axc" |
StringBuilder
StringBuffer 的继承结构图

StringBuffer和StringBuilder的比较用表格
| 比较项目 | StringBuffer | StringBuilder |
|---|---|---|
| 可变性 | 可变,允许通过多种方法(如 append、insert、delete 等)对字符串内容进行修改,修改操作在原对象上进行,不会产生新的对象(除非重新赋值) | 可变,提供与 StringBuffer 类似的修改方法,如 append、insert、delete 等,也是在原对象基础上进行修改 |
| 线程安全性 | 线程安全。其内部大部分方法都使用了synchronized关键字修饰,这使得在多线程环境下,多个线程访问同一个 StringBuffer 对象时可以正确地同步,保证数据的一致性和正确性,但这也导致了一定的性能损耗 | 非线程安全。在单线程环境下,由于不需要进行同步操作,其性能比 StringBuffer 更好。在多线程环境下如果没有正确的外部同步机制,可能会导致数据不一致的问题 |
| 性能(单线程) | 由于同步机制的存在,在单线程频繁操作字符串的场景下,性能稍逊一筹 | 在单线程环境下,特别是频繁进行字符串操作(如大量的 append 操作)时,性能优于 StringBuffer,因为它不需要额外的同步开销 |
| 性能(多线程) | 可以安全地在多线程环境下使用,虽然同步机制会带来性能损失,但保证了数据的准确性 | 在多线程环境下,如果没有外部的同步措施,可能会出现数据错误,不过如果正确地进行外部同步(如使用锁),在性能优化较好的情况下可能会接近或优于 StringBuffer 的性能,但代码复杂度会增加 |
| 适用场景 | 适用于多线程环境下对字符串进行修改的场景,例如在多个线程可能同时访问和修改同一个字符串对象的服务器端程序、共享资源处理等情况 | 适用于单线程环境下对字符串进行高效操作的场景,如在一个简单的本地工具程序、临时字符串处理等情况下进行大量的字符串构建或修改操作 |
| 初始容量 | 可以通过构造函数指定初始容量,默认容量为 16。如果预估字符串长度变化较大,可以指定合适的初始容量以减少扩容操作 | 与 StringBuffer 类似,可以通过构造函数指定初始容量,默认容量为 16,也能在一定程度上通过合理设置初始容量优化性能 |
| 扩容策略 | 当内容长度超过容量时会自动扩容,一般扩容策略是新容量 = 旧容量 * 2 + 2 | 扩容策略与 StringBuffer 相同,当内容长度超过容量时会自动扩容,新容量 = 旧容量 * 2 + 2 |
相关文章:
Java基础-String Class(字符串类)
String Java String 类概览 String 类是 Java 中最常用的类之一,用于处理字符串。以下是 String 类的主要特性和操作: 特性/操作描述不可变性String 对象一旦创建就不能被修改创建方式使用双引号 “” 或 String 构造函数字符串池Java 维护字符串常量池…...
《Linux服务与安全管理》| 服务进程与网络配置
《Linux服务与安全管理》| 服务进程与网络配置 目录 《Linux服务与安全管理》| 服务进程与网络配置 (1) 写出查看NetworkManager服务状态的命令。 (2) 写出查看NetworkManager服务自启动状态的命令。 (3࿰…...
No.15 笔记 | CSRF 跨站请求伪造
目录 一、基础知识 (一)cookie 和 session、同源策略 (二)CSRF 原理 二、CSRF 类型 (一)GET 类型 (二)POST 类型 三、CSRF 实例讲解 (一)真实案例 &am…...
解决linux中pip速度过慢问题
在 Linux 系统下,如果你发现使用 pip 下载 Python 库时速度非常慢,可以考虑以下几种方法来加速下载: 使用 pip 的 -i 选项: 如果你只想临时使用其他镜像,可以在安装时加上 -i 选项: pip install package_n…...
FlinkSQL中 的 双流JOIN
在 Flink SQL 中,流与流的 JOIN 是一种复杂的操作,因为它涉及到实时数据的无界处理。理解 Flink SQL 流与流 JOIN 的底层原理和实现需要从多个角度来分析,包括 状态管理、事件时间处理、窗口机制 以及 内部数据流处理模型 等。下面将从这些角…...
Mysql(五) --- 数据库设计
文章目录 前言1.范式1.1.第一范式1.1.1 定义1.1.2.例子 1.2.第二范式1.2.1 定义1.2.2 例子1.2.3.不满足第二范式可能会出现的问题 1.3.第三范式1.3.1 定义2.3.2 示例 2. 设计过程3. 实体-关系图3.1 E-R图的基本组成3.2 关系的类型3.2.1 一对一关系(1:1)3.2.2 ⼀对多关系(1:N)3.…...
po框架的了解和应用
https://www.cnblogs.com/xiaolehong/p/18458470 笔记 任务:1、通过po框架输入测试报告 2、编写自动化测试框架 3、总结测试讲解稿 自动化测试框架概念: 自动化测试框架是一个集成体系,这个体系中包含测试功能的函数、测试数据源、测试对以及重要的模块。 作用:用于解决或…...
Linux云计算 |【第四阶段】RDBMS2-DAY5
主要内容: PXC概述、部署PXC(自动故障恢复测试)、存储引擎、读锁/写锁、表锁/行锁、常用的存储引擎介绍 一、PXC概述 PXC(Percona XtraDB Cluster,简称PXC集群),是基于Galera的MySQL高可用集群…...
从0开始深度学习(9)——softmax回归的逐步实现
文章使用Fashion-MNIST数据集,做一次分类识别任务 Fashion-MNIST中包含的10个类别,分别为: t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙&…...
Cannot inspect org.apache.hadoop.hive.serde2.io.HiveDecimalWritable 问题分析处理
报错; org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.UnsupportedOperationException: Cannot inspect org.apache.hadoop.hive.serde2.io.HiveDecimalWritable 该问题常见于parquet格式hive表查询时,一般原因为hive表对应数据文件元数据对应格式与…...
电子取证新视角:USB键盘流量提取密码方法研究与实现
0x01 引言 在当今数字化时代,USB设备的广泛使用使得信息安全和电子取证领域面临着新的挑战与机遇。特别是USB键盘,作为一种常见的输入设备,其流量中可能包含用户输入的敏感信息,如密码和其他私人数据。因此,研究USB键…...
Tongweb7049m4+THS6010-6012配置故障轉移+重試机制(by lqw)
使用场景 1.ths代理tongweb多套后端,假如有其中一套tongweb因为服务器重启或者宕机后没有及时启动,导致ths一直轮询在这个出故障的节点上。 2.即使在tongweb重启了,有的应用启动也需要一定的时间,这个时候只是启动了应用端口&…...
在线客服系统网站源码-网页聊天客服实现代码
源码简介 在线客服系统 – 网上客服系统,在线客服系统网站源码。 消息预知功能就是别人在聊天框打字你都能看到 1.新增客服坐席消息互动,客服之间可以互相接收消息,可以智能分配 2.新增消息预知功能,可提前预知访客已输入未发…...
JioNLP:一款实用的中文NLP预处理工具包
一、什么是 JioNLP? JioNLP是一个面向NLP开发者的工具包,提供了常见的中文文本预处理、解析等功能,使用简单、高效准确、无需配置,可极大加快NLP项目的开发进度。 主要特点包括: 代码开源,使用MIT协议功能丰富,涵盖多个NLP预处理需求使用简单,无需复杂配置即可调用准确高效…...
GR-ConvNet论文 学习笔记
GR-ConvNet 文章目录 GR-ConvNet前言一、引言二、相关研究三、问题阐述四、方法A.推理模块B.控制模块C.模型结构D.训练方法E.损失函数 五、评估A.数据集B.抓取评判标准 六、实验A.设置B.家庭测试物体C.对抗性测试物体D.混合物体 七、结果A.康奈尔数据集B.Jacquard数据集C.抓取新…...
windows环境批量删除指定目录下的全部指定文件
写在开头: 1. 涉及文件删除,先在小范围内测试(更改D:\扫描文件路径) 2. 命令会递归该目录下的所有文件 命令: forfiles /p D:\ /s /m _maven.repositories /c "cmd /c del path"解释: /p D:\ …...
水深探测仪的作用和使用方法
在水域救援的行动里,救援人员时刻面临着复杂多变、充满未知的水域状况。当接到救援任务奔赴现场,那片需要涉足的水域就像一个神秘莫测的异世界,挑战着所有人的认知与勇气。 水深探测仪作为一种专用于测量水域深度的设备,通过声波和…...
Leetcode 搜索插入位置
这段代码的核心思想是 二分查找,用于在一个已经排序的数组中查找目标值的位置。如果目标值存在于数组中,返回它的索引;如果目标值不存在,返回它按顺序应该插入的位置。 算法思想步骤: 定义左右边界: 我们使…...
jsp怎么实现点赞功能
在JSP中实现点赞功能通常涉及前端页面的设计、后端逻辑处理以及数据存储。为了实现点赞功能,你可以使用以下步骤: 前端(JSP页面)设计 前端部分包括显示点赞按钮,并通过Ajax发送点赞请求,以避免页面刷新。 …...
取消microsoft edge作为默认浏览器 ,修改方法,默认修改不了的原因
将Microsoft Edge或其它浏览器设置为默认浏览器,可以尝试以下方法来解决此问题: 一, 通过浏览器设置修改:打开Microsoft Edge浏览器,单击右上角的“更多”按钮,然后选择“设置”。在设置页面左侧找到“默认…...
feishu2md:飞书文档转Markdown的技术实现与架构解析
feishu2md:飞书文档转Markdown的技术实现与架构解析 【免费下载链接】feishu2md 一键命令下载飞书文档为 Markdown 项目地址: https://gitcode.com/gh_mirrors/fe/feishu2md 飞书文档转Markdown工具feishu2md为技术团队提供了文档格式转换的标准化解决方案。…...
Kubernetes 存储性能优化:从持久卷到存储类
Kubernetes 存储性能优化:从持久卷到存储类 前言 哥们,别整那些花里胡哨的理论。今天直接上硬菜——我在大厂一线优化 Kubernetes 存储性能的真实经验总结。作为一个白天写前端、晚上打鼓的硬核工程师,我对性能的追求就像对鼓点节奏的把控一样…...
CTFHub | 解密MySQL、Redis、MongoDB流量中的隐藏Flag
1. 数据库流量分析入门:为什么需要Wireshark? 当你参加CTF比赛时,经常会遇到需要从数据库流量中寻找Flag的题目。这类题目通常会给你一个抓包文件(pcap格式),里面记录了MySQL、Redis或MongoDB等数据库的网络…...
SMUDebugTool:16核心独立调节与实时硬件监控的锐龙平台性能优化工具
SMUDebugTool:16核心独立调节与实时硬件监控的锐龙平台性能优化工具 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址…...
大多数加密API都不够用:量化团队真正需要的数据到底是什么?
如果你做过加密相关开发,无论是: 量化交易数据平台研究分析风控系统 你大概率都会经历一个阶段: 👉 API 接了一堆,但始终“不够用”。 常见的一个误区 很多人在刚开始做数据接入时,会觉得: …...
Qwen2-VL-2B-Instruct性能优化:Web服务并发请求处理与队列管理
Qwen2-VL-2B-Instruct性能优化:Web服务并发请求处理与队列管理 当你的AI图片分析服务突然火了,用户蜂拥而至,同时上传几十张图片要求分析,会发生什么?最直接的结果可能就是服务器卡死,用户看到“服务超时”…...
STM32标准库项目如何用VSCode一键编译下载?详解tasks.json与Makefile的联动配置
STM32标准库项目在VSCode中实现一键编译下载的终极指南 1. 为什么选择VSCode进行STM32开发? 传统嵌入式开发往往依赖于Keil、IAR等商业IDE,但这些工具存在几个明显痛点: 高昂的授权费用:商业IDE的许可证价格让个人开发者和小团队望…...
从沙子到芯片:保姆级图解CMOS制造18步核心工艺(附高清流程图)
从沙子到芯片:图解CMOS制造18步核心工艺 想象一下,你手中智能手机的核心处理器,其内部晶体管数量已突破百亿级——这相当于将整个银河系的恒星数量压缩到指甲盖大小的硅片上。而这一切的起点,竟是海滩上最普通的沙子。本文将用18张…...
RWKV7-1.5B-g1a开源大模型落地:无需高端A100,RTX4090即可跑满多语言生成能力
RWKV7-1.5B-g1a开源大模型落地:无需高端A100,RTX4090即可跑满多语言生成能力 1. 模型简介 rwkv7-1.5B-g1a 是基于新一代 RWKV-7 架构的开源多语言文本生成模型,专为实际应用场景优化。这个1.5B参数的模型在保持出色生成能力的同时࿰…...
告别复制粘贴!用ABAP类CL_SALV_BS_RUNTIME_INFO自动化获取任意ALV报表数据
告别复制粘贴!用ABAP类CL_SALV_BS_RUNTIME_INFO自动化获取任意ALV报表数据 在SAP系统的日常开发中,ABAP程序员经常需要从各种ALV报表中提取数据用于二次处理。传统的手动复制粘贴方式不仅效率低下,还容易出错。本文将介绍如何利用CL_SALV_BS_…...
