String类及其常用方法
文章目录
- 1.String类的特性与使用
- 1.1 String类的特性
- 1.2 String对象的创建方式
- 1.3 String 的使用(不同的拼接操作)
- 2.String常用方法
- 2.1 String的常用方法一
- 2.2 String常用方法二
- 2.3 String常用方法三
1.String类的特性与使用
1.1 String类的特性
String 代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
特性:
1.String是声明为final的,不可被继承。
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小。
3.String内部定义了final char[] value用于存储字符串数据。
4.String:代表不可变的字符序列。简称:不可变性。
这里的不可变说的是存储在常量池中的字符串常量(字符数组 char value[])的值是不可变的, 而不是String类型的变量的值是不可变的。)
体现:①当对字符串重新赋值时,需要重新指定区域赋值,不能使用原有的value进行赋值。
String s1 = "abc"; //字面量的定义方式
String s2 = "abc";
s1 = "hello";System.out.println(s1 == s2); //比较s1和s2的地址值
System.out.println(s1);
System.out.println(s2);
测试结果如下:
②当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
String s2 = "abc";
String s3 = "abc";
s3 += "def";System.out.println(s3); //abcdef
System.out.println(s2); //abc
System.out.println(s2 == s3); //false
测试结果如下:
③当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
String s4 = "abc";
String s5 = s4.replace('a', 'z');System.out.println(s4);
System.out.println(s5);
System.out.println(s4 == s5);
测试结果如下:
5.通过"字面量"的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
6.字符串常量池中是不会存储相同内容的字符串的。
1.2 String对象的创建方式
- 通过字面量定义的方式
此时定义的数据声明在方法区中的字符串常量池中。
2.通过new + 构造器的方式
此时创建的String对象保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
@Test
public void test2(){//通过字面量定义的方式://此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。String s1 = "javaEE";String s2 = "javaEE";//通过new + 构造器的方式:此时的s3和s4保存的地址值,//是数据在堆空间中开辟空间以后对应的地址值。String s3 = new String("javaEE");String s4 = new String("javaEE");System.out.println(s1 == s2);//trueSystem.out.println(s1 == s3);//falseSystem.out.println(s1 == s4);//falseSystem.out.println(s3 == s4);//false}
测试结果如下:
下面通过这样一段代码来加深一下对String对象创建方式的理解:
Person p1 = new Person("Tom", 12);
Person p2 = new Person("Tom", 12);System.out.println(p1.name.equals(p2.name)); //true
System.out.println(p1.name == p2.name); //truep1.name = "Jerry";
System.out.println(p2.name); //Tom
思考上述代码段的运行结果是怎么样子的呢?
首先第一个输出是true,因为String类重写了Object类的equals方法,比较的是String对象的值,所以只要字符串的值相同,结果就为true。
第二个也为true,这是因为在用构造器传参的过程中,其实是以字面量的方式声明的p1.name和p2.name,所以p1.name和p2.name是存储在方法区中的字符串常量池中的,且是同一份。只不过p1和p2这两个Person类的对象是声明在了堆中的不同地方而已,p1和p2两对象的name属性值的地址是一样的,都指向方法区的字符串常量池的同 一片地址空间。 内存结构如下图所示:
所以这个时候如果试图改变p1的name值(以字面量的方式),那么就是在常量池中另外开辟了一片空间,p2的name值不会受到影响,还是“Tom”。
1.3 String 的使用(不同的拼接操作)
思考下述关于String对象连接操作的代码段的运行结果。
public void test3(){String s1 = "javaEE";String s2 = "hadoop";String s3 = "javaEEhadoop";String s4 = "javaEE" + "hadoop";String s5 = s1 + "hadoop";String s6 = "javaEE" + s2;String s7 = s1 + s2;System.out.println(s3 == s4);//trueSystem.out.println(s3 == s5);//falseSystem.out.println(s3 == s6);//falseSystem.out.println(s3 == s7);//falseSystem.out.println(s5 == s6);//falseSystem.out.println(s5 == s7);//falseSystem.out.println(s6 == s7);//false
}
下面给出运行结果:
为什么会这样呢?这是因为String对象的连接操作有下述三条结论:
1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
2.只要其中有一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中。
由结论1和2,不难验证出上述代码段的运行结果。下面给出内存结构图辅助理解:
其中,intern()方法是String类的一个方法,其返回值的内容声明在常量池中。
2.String常用方法
2.1 String的常用方法一
- **int length():**返回字符串的长度: return value.length
String s1 = "HelloWorld";System.out.println(s1.length());
测试结果如下:
- char charAt(int index): 返回某索引处的字符return value[index]
System.out.println(s1.charAt(0));
System.out.println(s1.charAt(9));
System.out.println(s1.charAt(10));
测试结果如下:
可见,若索引值超过String下标时,会报下标越界的错误。
- **boolean isEmpty():**判断是否是空字符串:return value.length == 0
String s1 = "HelloWorld";
String s2 = "";
System.out.println(s1.isEmpty());
System.out.println(s2.isEmpty());
测试结果如下:
- **String toLowerCase():**使用默认语言环境,将 String 中的所有字符转换为小写
String s1 = "HelloWorld";
String s2 = s1.toLowerCase();
System.out.println(s1); //s1不可变的,仍然为原来的字符串
System.out.println(s2); //改成小写以后的字符串
测试结果如下:
- **String toUpperCase():**使用默认语言环境,将 String 中的所有字符转换为大写
String s1 = "HelloWorld";
String s2 = s1.toUpperCase();
System.out.println(s1); //s1不可变的,仍然为原来的字符串
System.out.println(s2); //改成大写以后的字符串
测试结果如下:
- **String trim():**返回字符串的副本,忽略前导空白和尾部空白
String s3 = " he llo world ";
String s4 = s3.trim();
System.out.println("-----" + s3 + "-----");
System.out.println("-----" + s4 + "-----");
测试结果如下:
- **boolean equals(Object obj):**比较字符串的内容是否相同
- **boolean equalsIgnoreCase(String anotherString):**与equals方法类似,忽略大小写
String s1 = "HelloWorld";
String s2 = "helloworld";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));
测试结果如下:
- **String concat(String str):**将指定字符串连接到此字符串的结尾。 等价于用“+”
String s3 = "abc";
String s4 = s3.concat("def");
System.out.println(s4);
测试结果如下:
- **int compareTo(String anotherString):**比较两个字符串的大小
String s5 = "abc";
String s6 = new String("abe"); //这个时候和字符串是怎样赋的值已经没有关系了,因为比较的是内容
System.out.println(s5.compareTo(s6));//涉及到字符串排序
测试结果如下:
- **String substring(int beginIndex):**返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。(即从指定索引位置到结尾)
String s7 = "北京尚硅谷教育";
String s8 = s7.substring(2)
System.out.println(s7);
System.out.println(s8);
测试结果如下:
- String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。(左闭右开)
String s7 = "北京尚硅谷教育";
String s9 = s7.substring(2, 5);
System.out.println(s7);
System.out.println(s9);
测试结果如下:
2.2 String常用方法二
- **boolean endsWith(String suffix):**测试此字符串是否以指定的后缀结束
String str1 = "hellowworld";
boolean b1 = str1.endsWith("rld"); //形参处可以是单个的字符,也可以是字符串
System.out.println(b1);
测试结果如下:
- **boolean startsWith(String prefix):**测试此字符串是否以指定的前缀开始
String str1 = "hellowworld";
boolean b2 = str1.startsWith("He"); //形参处可以是单个的字符,也可以是字符串
boolean b3 = str1.startsWith("he"); //形参处可以是单个的字符,也可以是字符串
System.out.println(b2);
System.out.println(b3);
测试结果如下:
- **boolean startsWith(String prefix, int toffset):**测试此字符串从指定索引开始的子字符串是否以指定前缀开始
String str1 = "hellowworld";
boolean b3 = str1.startsWith("ll",2); //从str1的指定toffset处开始的字符串是否以prefix开始
System.out.println(b3);
测试结果如下:
- **boolean contains(CharSequence s):**当且仅当此字符串包含指定的 char 值序列时,返回 true
String s1 = "helloworld";
String s2 = "wor";
System.out.println(s1.contains(s2));
测试结果如下:
- **int indexOf(String str):**返回指定子字符串在此字符串中第一次出现处的索引
- **int indexOf(String str, int fromIndex):**返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
String str1 = "helloworld";
System.out.println(str1.indexOf("lo"));
System.out.println(str1.indexOf("lol"));
System.out.println(str1.indexOf("lo", 5));
测试结果如下:
- **int lastIndexOf(String str):**返回指定子字符串在此字符串中最右边出现处的索引
- **int lastIndexOf(String str, int fromIndex):**返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or"));
System.out.println(str3.lastIndexOf("or", 6));
测试结果如下:
2.3 String常用方法三
- **String replace(char oldChar, char newChar):**返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String str1 = "北京尚硅谷教育北京";
String str2 = str1.replace('北', '东');
System.out.println(str1);
System.out.println(str2);
测试结果如下:
- **String replace(CharSequence target, CharSequence replacement):**使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
String str1 = "北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
System.out.println(str3);
测试结果如下:
- **String replaceAll(String regex, String replacement):**使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。(regex:全称为:regular expression(正则表达式))
String str = "12hello34world5java7891mysql456";
//把字符串中的数字替换成',',如果结果中开头和结尾有','的话去掉
String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$", "");
System.out.println(string);
测试结果如下:
- **String replaceFirst(String regex, String replacement):**使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
- **boolean matches(String regex):**告知此字符串是否匹配给定的正则表达式。
String str = "12345";
//判断str字符串中是否全部有数字组成,即有1-n个数字组成
boolean matches = str.matches("\\d+");
System.out.println(matches);
String tel = "0571-4534289";
//判断这是否是一个杭州的固定电话
boolean result = tel.matches("0571-\\d{7,8}");
System.out.println(result);
测试结果如下:
- **String[] split(String regex):**根据给定正则表达式的匹配拆分此字符串。
- **String[] split(String regex, int limit):**根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
String str = "hello|world|java";
String[] strs = str.split("\\|");
for (int i = 0; i < strs.length; i++) {System.out.println(strs[i]);
}
System.out.println("***********************");
str2 = "hello.world.java";
String[] strs2 = str2.split("\\.");
for (int i = 0; i < strs2.length; i++) {System.out.println(strs2[i]);
}
测试结果如下:
相关文章:

String类及其常用方法
文章目录 1.String类的特性与使用1.1 String类的特性1.2 String对象的创建方式1.3 String 的使用(不同的拼接操作) 2.String常用方法2.1 String的常用方法一2.2 String常用方法二2.3 String常用方法三 1.String类的特性与使用 1.1 String类的特性 Stri…...
1094. 拼车
说在前面 🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。 题目描述 车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不…...

Docker进阶:深入了解容器数据卷
Docker进阶:深入了解容器数据卷 一、前言二、容器数据卷的作用三、容器数据卷的使用方法四、实战--使用docker部署前端项目(数据卷挂载)4.1 重要:准备工作,先在本地创建挂载目录4.2 启动一个临时的nginx容器࿰…...
升级版本彻底解决bootstrap-table-fixed-columns固定列后行对不齐问题
升级到bootstrap-table和bootstrap-table-fixed-columns版本都升级到v1.22.3版本以上,即可解决该问题 bootstrap-table:bootstrap-table/dist/bootstrap-table.min.css at develop wenzhixin/bootstrap-table GitHub bootstrap-table-fixed-columns&…...
打破边界:深入探索STUN在实现无缝NAT穿越和WebRTC通信中的核心作用
引言 STUN是一个网络协议,设计用于帮助在网络地址转换(NAT)后面的设备发现其公网地址和端口号。通过允许这些设备发现自己从外部看到的地址,STUN使得它们能够在NAT或防火墙背后建立端到端的通信,这对于VoIP、视频会议…...
浅谈 前端的动态绑定属性
目录 前言1. 基本知识2. Demo 前言 作为Java开发者,从开发转到全栈,前端好些细节都需要科普,这不就来个动态绑定属性 起因是这个: <uni-tr> <uni-td align"center" :rowspan"checkTypesCount 1"…...
Sklearn支持向量机
支持向量机(Support Vector Machine, SVM)是一种常用的分类算法,它可以用于解决二分类和多分类问题。在Python中,你可以使用Sklearn库来实现SVM。下面是一个简单的例子,展示了如何使用Sklearn进行SVM分类。 # 导入必要…...

【Lazy ORM】 小工具 acw 本地客户端 你负责点击页面,他负责输出代码
介绍 wu-smart-acw-client 简称acw-client,是一个基于Lazy ORM定制的客户端代码生成小工具 Lazy ORM 小工具 acw 本地客户端 你负责点击页面,他负责输出代码安装 <dependency><groupId>top.wu2020</groupId><artifactId>wu-sma…...

《详解:鸿蒙NEXT开发核心技术》
我们现在都知道鸿蒙作为一个国产的全栈自研系统,经过国家主推后。已经引起人们很大的关注,其中作为开发者来说;许多一线大厂已经与其华为鸿蒙展开原生应用的合作了,目前了解到已经有200家。而之后出现了很多的高薪鸿蒙开发岗位&am…...

快速排序 刷题笔记
思路 分治双指针 在每个区间选定一个基准目标 两个指针从数组的两边向中间推进 使用 while循环判断 do {i;}while(q[i]<x); do{j--;}while(q[j]>x); 每次这样做完就会找到q[i]>x,,,,q[j]小于x 此时我们交换 q[i] ,q[j]于是小于x的数分到了小于x的一侧 大…...

DAY by DAY 史上最全的Linux常用命令汇总----man
man是按照手册的章节号的顺序进行搜索的。 man设置了如下的功能键: 功能键 功能 空格键 显示手册页的下一屏 Enter键 一次滚动手册页的一行 b 回滚一屏 f 前滚一屏 q 退出man命令 h 列出所有功能键 /word 搜索word字符串 注意:…...

十六、接口隔离原则、反射、依赖注入
接口隔离原则、反射、特性、依赖注入 接口隔离原则 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。 五种原则当中的i 上一章中的接口,即契约。 契约就是在说两件事,甲方说自己不会多要,乙方会在…...
Docker 进阶
1、容器数据卷 什么是容器数据卷? 就是当容器内存在了mysql,在里面书写了数据,如果容器删除了,那么数据也就没有了,通过容器数据卷的技术,可以让容器内的数据持久化到Linux服务器上 操作 #docker run -…...

科研学习|论文解读——一种修正评分偏差并精细聚类中心的协同过滤推荐算法
知网链接 一种修正评分偏差并精细聚类中心的协同过滤推荐算法 - 中国知网 (cnki.net) 摘要 协同过滤作为国内外学者普遍关注的推荐算法之一,受评分失真和数据稀疏等问题影响,算法推荐效果不尽如人意。为解决上述问题,本文提出了一种改进的聚类…...

云计算项目十一:构建完整的日志分析平台
检查k8s集群环境,master主机操作,确定是ready 启动harbor [rootharbor ~]# cd /usr/local/harbor [rootharbor harbor]# /usr/local/bin/docker-compose up -d 检查head插件是否启动,如果没有,需要启动 [rootes-0001 ~]# system…...
2.经典项目-海量用户即使通讯系统
1.实现功能-完成注册用户 完成用户注册的步骤(客户端) 1.将User移动到common/message文件夹下 2.在message中新增注册用户的结构体 const (LoginMesType "LoginMes"LoginResMesType "LoginResMes"RegisterMesType "RegisterMes"…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的交通标志识别系统详解(深度学习模型+UI界面代码+训练数据集)
摘要:本篇博客详细介绍了利用深度学习构建交通标志识别系统的过程,并提供了完整的实现代码。该系统采用了先进的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等早期版本进行了性能评估对比,分析了性能指标如mAP、F1 Score等。文章深入探…...

VMware下创建虚拟机
Centos7是比较常用的一个Linux发行版本,在国内的使用比例比较高 安装完VMware一定要检查虚拟网卡有没有安装成功,如果没有VMnet1和VMnet8 虚拟机是无法上网的,就需要卸载重启电脑重新安装 控制面板—网络和Internet—网络连接 快捷方式打开&a…...

基于Ambari搭建大数据分析平台
一、部署工具简介 1. Hadoop生态系统 Hadoop big data ecosystem in Apache stack 2. Hadoop的发行版本 Hadoop的发行版除了Apache的开源版本之外,国外比较流行的还有:Cloudera发行版(CDH)、Hortonworks发行版(HDP)、MapR等&am…...
Vue template到render过程,以及render的调用时机
Vue template到render过程 vue的模版编译过程主要如下:template -> ast -> render函数(1)调用parse方法将template转化为ast(抽象语法树)(2)对静态节点做优化(3)生…...

使用osqp求解简单二次规划问题
文章目录 一、问题描述二、数学推导1. 目标函数处理2. 约束条件处理 三、代码编写 一、问题描述 已知: m i n ( x 1 − 1 ) 2 ( x 2 − 2 ) 2 s . t . 0 ⩽ x 1 ⩽ 1.5 , 1 ⩽ x 2 ⩽ 2.5 min(x_1-1)^2(x_2-2)^2 \qquad s.t. \ \ 0 \leqslant x_1 \leqslant 1.5,…...
P3 QT记事本(3.4)
3.4 文件选择对话框 QFileDialog 3.4.1 QFileDialog 开发流程 使用 QFileDialog 的基本步骤通常如下: 实例化 :首先,创建一个 QFileDialog 对象的实例。 QFileDialog qFileDialog;设置模式 :根据需要设置对话框的模式&…...

智能对联网页小程序的仓颉之旅
#传统楹联遇上AI智能体:我的Cangjie Magic开发纪实 引言:一场跨越千年的数字对话 "云对雨,雪对风,晚照对晴空"。昨天晚上星空璀璨,当我用仓颉语言写下第一个智能对联网页小程序的Agent DSL代码时࿰…...

阿里云 RDS mysql 5.7 怎么 添加白名单 并链接数据库
阿里云 RDS mysql 5.7 怎么 添加白名单 并链接数据库 最近帮朋友 完成一些运维工作 ,这里记录一下。 文章目录 阿里云 RDS mysql 5.7 怎么 添加白名单 并链接数据库最近帮朋友 完成一些运维工作 ,这里记录一下。 阿里云 RDS MySQL 5.7 添加白名单1. 登录…...
81 实战一:给root目录扩容
添加一块100G硬盘 vgextend centos /dev/sdb1 /dev/sdc lvextend -L +120G /dev/centos/root xfs_growfs /dev/centos/root df -h 看是否扩容成功 82 实战二:给swap空间扩容 添加一块20G硬盘 fdisk -l 可以看到新添加的硬盘 vgextend centos /dev/sdd …...
Build a Large Language Model (From Scratch) 序章
关于本书 《从零构建大型语言模型》旨在帮助读者全面理解并从头创建类似GPT的大型语言模型(LLMs)。 全书首先聚焦于文本数据处理的基础知识和注意力机制的编码,随后指导读者逐步实现一个完整的GPT模型。书中还涵盖了预训练机制以及针对文本…...
Flink 高可用集群部署指南
一、部署架构设计 1. 集群架构 graph TDClient([客户端]) --> JM1[JobManager 1]Client --> JM2[JobManager 2]Client --> JM3[JobManager 3]subgraph ZooKeeper集群ZK1[ZooKeeper 1]ZK2[ZooKeeper 2]ZK3[ZooKeeper 3]endsubgraph TaskManager集群TM1[TaskManager 1…...
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询 🚀 在社交网络、权限图谱、推荐系统等应用场景中,关系链深度和复杂度远超传统关系型数据库的表达能力。本文基于 ABP VNext 框架,集成 Neo4j 图数据库,构建一套高…...
Elasticsearch 海量数据写入与高效文本检索实践指南
Elasticsearch 海量数据写入与高效文本检索实践指南 一、引言 在大数据时代,企业和组织面临着海量数据的存储与检索需求。Elasticsearch(以下简称 ES)作为一款基于 Lucene 的分布式搜索和分析引擎,凭借其高可扩展性、实时搜索和…...

为什么说数列是特殊的函数
文章目录 前情概要函数特性特殊之处典例剖析前情概要 高三的学生几乎都听老师说过,数列是特殊的函数,那么如何理解这句话呢,无外乎需要关注两点:①函数性,②特殊性,以下举例说明,帮助各位学子理解。 函数特性 既然是按照一定的次序排列而成的一列数字,那么这些数字(…...