初始Java篇(JavaSE基础语法)(8)认识String类(上)

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:JavaSE

简单介绍:在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。

常用操作String的方法

字符串构造

String类提供的构造方式非常多,常用的就以下三种:

方式一:直接赋值。

String s1 = "Hello";

方式二:使用创建对象的方法。

 String s2 = new String("Hello");

方式三:在方法二的基础上,传入字符数组作为参数。 

char[] ch = {'H','e','l','l','o'};
String s3 = new String(ch);

示例: 

上面三种构造情况,用专业术语总结就是:使用常量串构造,new Sting对象,使用字符数组进行构造。

注意:

1. 我们在前面简单学习了一下String类,它是一个引用数据类型,内部存储的是一个地址,而不是字符串本身。

2. String类的字符串常量是储存在一个名为value的字符数组中的。

3. Java中" "(双引号)里的内容都被认作是String类型对象。简单理解就是字符串。

String对象的比较

下面我们就来深入理解为什么==比较的不是String对象的内容?

public class Test {public static void main(String[] args) {String s1 = new String("Hello");String s2 = new String("Hello");}
}

因为数组也是对象,因此也是在堆区中的。只不过为了更好的观察,我就写了两个堆区,实际上只有一个堆区。 

当然,我们也可以通过调试来观察。

 那么要怎么比较呢?其实我们在多态的学习时,已经初步的学习过了。

equals方法——比较对象的内容

equals方法比较的对象里面的内容是啥?比如,我们刚刚写的s1与s2,这两个引用的对象是不一样的,但是这两个引用的对象的内容却是一样的,都是Hello。

注意:

String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较 :

1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true。也就是上面的s1与s2所引用的对象。

2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false。

3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false。

4. 按照字典序,从前往后逐个字符进行比较,如果是就返回true,否则就返回false。

注意:

如果上面我们在比较的字符串引用是直接赋值创建的,那么使用==比较的最终结果就是true。

这里就会有小伙伴疑惑这是为啥呢?难道这两个引用所指向的对象是一样的?没错,这两个引用所指向的对象就是一个对象。

在Java中,字符串字面量(例如 "Hello")是存储在字符串常量池中。当你使用 String s1 = "Hello";

和 String s1 = "Hello"; 这种方式声明字符串时,实际上s1和s2都指向了常量池中同一个"Hello"实例。因此,使用 s1 == s2 比较时,结果都是 true,因为它们引用的是同一个对象。

然而,当你使用 String s1 = new String("Hello"); 方式创建字符串时,会创建一个新的字符串对象,即使内容相同,这个新对象也会在堆上分配独立的内存空间,而不是从字符串常量池中获取。所以,String s1 = new String("Hello"); 和 String s1 = new String("Hello"); 分别创建了两个不同的字符串对象,尽管它们的内容都是 "Hello",但它们在内存中的地址不同。因此,使用 s1 == s2 比较时结果为 false,因为它们指向不同的对象实例。但是,如果你使用 s1.equals(s2) 方法进行比较,结果会是 true,因为 equals 方法比较的是对象的内容,而不是它们的引用。

compareTo——比较的是字符串大小

compareTo和C语言中的strcmp函数的功能是相似的。都是比较字符串的大小。既然是比较大小,那么返回的就是一个 int 类型的值。

比较规则:

1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值。

2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值(与strcmp的差异)

public class Test {public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("ac");String s3 = new String("abc");String s4 = new String("abg");//长度不同,返回的结果就是长度的差值System.out.println(s1.compareTo(s2));//长度一样,返回的就是一个一个的结果(都一样,返回0)System.out.println(s1.compareTo(s3));//长度一样,返回的就是一个一个的结果(c和g不同,返回的就是c-g的值)System.out.println(s1.compareTo(s4));}
}

compareToIgnoreCase——忽略大小写的比较

和compareTo的比较方法一样,但是是忽略大小写的比较

字符串查找 

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:

方法功能
char charAt(int index)返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException 异常
int indexOf(int ch)返回ch第一次出现的位置,没有返回-1
int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1
int indexOf(String str)返回str第一次出现的位置,没有返回-1
int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1
int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch, int fromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1
int lastIndexOf(String str)从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1

示例:

public class Test {public static void main(String[] args) {String s = "aaabbbcccaaabbbccc";System.out.println(s.charAt(3));//获取下标为3位置的字符System.out.println(s.indexOf(97));//返回ASCII码值为97的字符在s中第一次出现的位置System.out.println(s.indexOf(97,5));//从下标为5的位置的开始找System.out.println(s.indexOf("cc"));//返回的是"cc"在s1中第一次出现的位置//而带有last前缀的,则是从字符串的末尾开始寻找}
}

注意:

1. 字符串是的下标是从0开始的和数组是一致的。 

2. 上述方法都是实例方法,也就是我们得先创建一个类的实例对象才行。

字符串的转化

数值和字符串转化

valueOf方法  

从上面,我们可以看出来:String有很多重载的 valueOf 方法。

既然数值可以转换为字符串,那么字符串也可以转换位数值。

parse+包装类 

整数变成字符串还有一种方法:整数+字符串——>字符串。

下面我们就来看看一个神奇的代码:

public class Test {public static void main(String[] args) {//前面是简单的数字运算,但是后面加了字符串,因此结果就变成了一个字符串System.out.println(99+1+" Hello");//前面是字符串,虽然后面是数字相加,但是按照执行顺序的话是就是字符串加数字,因此最终的结果就是把数字加到了字符串后面System.out.println("Hello "+99+1);//这里加了括号,改变了执行顺序,是先执行数字运算,再和字符串相加System.out.println("Hello "+(99+1));}
} 

因此,这个方法虽然不够正规,但是我们也是可以了解的。 

其实,从这里我们也就可以看出来,Java当中只要知道使用一个类其中一个方法,那么其他的重载方法也就知道怎么使用了。 

大小写转换

public class Test {public static void main(String[] args) {String s = "Hello";System.out.println(s.toUpperCase());System.out.println(s.toLowerCase());}
}

toUpper——就是将字符串中所有字母全部变成大写。

toLower——就是把字符串中所有字母全部变成小写。

字符串转数组 

把字符串的内容转换为数组内容,并且一个一个的输出。

格式化

public class Test {public static void main(String[] args) {//因为这里变量还没有创建完,因此不适合用变量名来调用这个format方法//这里就两个参数,应该是按照什么样的格式,一个是传给格式的参数String s = String.format("%d-%d-%d",2024,5,10);System.out.println(s);}
}

字符串替换 

使用一个指定的字符串替换掉已有的字符串数据,可用的方法如下:

方法功能
String replaceAll(String regex, String replacement)替换所有的指定内容
String replaceFirst(String regex, String replacement)替换遇到的首个符合要求内容(符合要替换的内容)

注意:由于字符串是不可变对象,替换不会修改当前字符串,而是产生一个新的字符串对象,给到我们原来的引用。 (至于过程,我们后面会学习这个)

示例:

字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

可用方法如下:

方法功能
String[] split(String regex)将字符串按照给的字符串全部拆分
String[] split(String regex, int limit)将字符串以给的字符串的格式,拆分为limit组

示例: 

public class Test {public static void main(String[] args) {String s = "I say Hello World";//根据 字符串空格 来拆分这个字符串,变成若干个子字符串,并且用数组来接收String[] tmp = s.split(" ");for (String x : tmp) {System.out.println(x);}}
}

public class Test {public static void main(String[] args) {String s = "I say Hello World";//根据 字符串空格 来拆分这个字符串,变成两个子字符串,并且用数组来接收String[] tmp = s.split(" ",2);for (String x : tmp) {System.out.println(x);}}
}

上面是正常的拆分,但是还有些是不能正常来拆分的。就像下面这样

那么怎样才能正常划分呢?要加上转义字符才可以。

规则:

1. 字符串 "|"   "*"  "+"  "."  都得加上转义字符,前面加上 "\\" 。

2. 而如果是 "\\" ,那么就得写成 "\\\\" 。也就是两个 \\ 表示一个 \ ,而4个 \ 就表示两个 \ 。

3. 如果一个字符串中有多个分隔符,可以用 "|" 作为连字符.。

第二点想要表达的意思是如果原字符串中存在 \\ (有时候不存在一个 \ 的情况,例如在数字中 \ddd,这就变成了一个转义字符了,因此这时候如果我们要表述一个 \ ,就得用用两个 \\ ),而我们想要以这个来作为划分标准的话,怎么办呢?用两个 \\ ,肯定是不行的,因为这是表示一个 \ ,因此,我们就得用 \\ 表示一个 \ ,因此 \\\\ 就表示 \\ 了。

而第三点是啥意思呢?就是我们想要多个标准来划分字符串的话,那那个标准怎么写呢?如下所示:

上面这个就包含了我们上面的多种规则结合在一起。

好啦!本期 初始Java篇(JavaSE基础语法)(8)认识String类(上)的学习之旅就到此结束了!我们下一期再一起学习吧!

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

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

相关文章

leetcode算法笔记-算法复杂度

对于时间复杂度,主要包括三种情况: 渐进紧确界: O渐进上界: 渐进下界: 加法原则:不同的时间复杂度相加取阶数最高的 乘法原则:不同的时间复杂度相乘,结果为时间复杂度的乘积 阶乘…

电脑nvidia驱动和合适版本的duda--自用 回忆版

参考文献:http://t.csdnimg.cn/ecDuG 内容很多抄的这个,主要害怕链接失效 一、Ubuntu 18.04 安装NVIDIA显卡驱动 1、查看本机显卡能够配置的驱动信息 ubuntu-drivers devices所以可以看出,推荐 nvidia-driver-530 - distro non-free 2、安…

Kubernetes学习-深入Pod篇(一) 创建Pod,Pod配置文件详解

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Kubernetes渐进式学习-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 1.前言 我们在前面的文章讲解了Kubernetes的核心概念和服务部署&#x…

MyBatis-plus(一):快速入门

目录 一、MyBatis-plus 快速入门 1、原理 2、实体类命名规则 3、常见注解 4、主键 id 策略 5、使用 TableField 的常见场景 6、常用配置 二、核心功能 1、条件构造器 2、自定义 SQL 3、IService 接口 一、MyBatis-plus 快速入门 1、原理 MyBatisPlus 通过扫描实体…

Spark写Hbase如何提高Bulkload的速度

​   对于Hbase的Bulkload基本流程这里就不多介绍可以看Bulkload流程介绍,本问主要介绍如何提升Bulkload的方式。   很多时候我们在写HFile的时候都会进行repartition使用的是repartitionAndSortWithinPartitions,其中Spark也提供几种repartition的实…

蓝桥杯备战6.奖学金

P1093 [NOIP2007 普及组] 奖学金 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N 2e710,M 1e310; int a[N],pre[N]; int chi[N],math[N],eng[N],id[N],b[N]; struct s…

算法学习012-不同路径 c++动态规划算法实现 中小学算法思维学习 信奥算法解析

目录 C不同路径 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、运行结果 五、考点分析 六、推荐资料 C不同路径 一、题目要求 1、编程实现 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09…

Golang | Leetcode Golang题解之第78题子集

题目&#xff1a; 题解&#xff1a; func subsets(nums []int) (ans [][]int) {set : []int{}var dfs func(int)dfs func(cur int) {if cur len(nums) {ans append(ans, append([]int(nil), set...))return}set append(set, nums[cur])dfs(cur 1)set set[:len(set)-1]df…

什么是跨域?怎么解决跨域?为什么使用中间服务器就行?

文章目录 什么是跨域怎么解决跨域为什么使用中间服务器就行了呢 什么是跨域 跨域指的是在Web开发中&#xff0c;当一个网页的脚本试图访问不同域&#xff08;域名、协议或端口&#xff09;的资源时&#xff0c;就会发生跨域问题。同源策略&#xff08;Same-Origin Policy&…

计算概论学习笔记(2)

感谢北大李戈老师讲解的计算概论。 【道阻且长&#xff0c;行则将至】 很多年没有intensive coding&#xff0c;现在这个系列是coding retake&#xff0c;一点点回忆之前的知识&#xff0c;希望能重回到一线。主要内容包括C,C,Pytorch学术前沿项目学习和实践&#xff0c;预计…

iOS 安装cocoapds

注意 CocoaPods安装是基于ruby环境的&#xff0c;所以要安装CocoaPods先要安装Ruby环境&#xff0c;国内不能直接安装&#xff0c;只能通过VPN或淘宝的Ruby镜像来访问。 安装过程 gem sources --remove https://rubygems.org/ ** (注意是两个“-”&#xff0c;否则会移除失败) …

Spring STOMP-开启STOMP

通过Spring框架的spring-messaging和spring-websocket模块&#xff0c;提供了对WebSocket上STOMP的支持。一但你添加了这些依赖项&#xff0c;你就可以像下面这个示例一样&#xff0c;通过WebSocket公开一个STOMP端点&#xff1a; import org.springframework.web.socket.conf…

掌握文件重命名技巧:一次性处理多路径文件并赋予独立编号

在日常工作和生活中&#xff0c;我们经常需要处理大量的文件&#xff0c;而文件重命名则是一项非常常见的任务。如何高效地一次性处理多路径文件并赋予独立编号&#xff0c;成为许多用户关注的焦点。本文将介绍云炫文件管理器一些实用的文件重命名技巧&#xff0c;帮助您轻松应…

蓝桥杯备战7.宇宙总统

P1781 宇宙总统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 当时写cmp的时候没想到直接让string类型进行比较 #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N 2e710,M 1e310; int a[N],pre[N]; int chi[N],math…

Python3 笔记:Python的常量

常量&#xff08;constant&#xff09;&#xff1a;跟变量相对应&#xff0c;指第一次赋予值后就保持固定不变的值。 Python里面没有声明常量的关键字&#xff0c;其他语言像C/C/Java会有const修饰符&#xff0c;但Python没有。 Python中没有使用语法强制定义常量&#xff0c…

前后端完全开源!功能丰富的在线教室项目:Agora Flat

Agora Flat&#xff1a;高效集成的在线教室解决方案&#xff0c;重塑互动学习新体验。- 精选真开源&#xff0c;释放新价值。 概览 Agora Flat是在GitHub平台上公开分享的一个全面开源项目&#xff0c;它精心设计为一个高性能的在线教室解决方案&#xff0c;旨在便捷地搭建支持…

根据标签最大层面ROI提取原始图像区域(二)

今天要实现的任务还是提取肿瘤的感兴趣区域。 有两个文件&#xff0c;一个是nii的原始图像文件&#xff0c;一个是nii的标签文件。我们要实现的是&#xff1a;在标签文件上选出最大层面&#xff0c;然后把最大层面的ROI映射到原始图像区域&#xff0c;在原始图像上提裁剪出ROI…

容器镜像安全管理解析

目录 1. 镜像的层次结构与安全性2. 安全扫描工具3. 安全的最佳实践4. 安全策略实施 镜像安全在容器化和云原生应用中至关重要&#xff0c;因为容器镜像通常包含了应用及其依赖的所有必要组件&#xff0c;任何安全漏洞都可能成为攻击的入口点。 1. 镜像的层次结构与安全性 容器…

【DevOps】Linux 网络命令netstat详解

目录 一、netstat 命令的主要功能 常用 netstat 命令及选项 二、示例和用法 1. 查看所有连接和监听端口 2. 显示端口和进程信息 3. 使用 netstat 查看路由表 4. 查看接口统计 5. 查看服务和协议的统计信息 6. 持续监控网络状态 7. 组合使用 netstat 选项 8. 其他有用…

GEE案例——广东省梅州市梅县区松口镇的梅江横山水灾监测(利用sentinel-1和大津法计算洪水时序面积)

背景 2024年4月5日晚,广东省气象部门发布消息称,4月5日0时到20时,广东中北部出现了暴雨到大暴雨,其中从化吕田累计雨量最大达到225.7毫米。累计降水量达到大暴雨的地方还包括惠州龙门县永汉镇205.2毫米、清远佛冈县水头镇188.6毫米、韶关新丰县梅坑镇174.5毫米、河源东源县…