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浏览器,单击右上角的“更多”按钮,然后选择“设置”。在设置页面左侧找到“默认…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...