初始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 通过扫描实体…

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

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

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

题目: 题解: 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…

计算概论学习笔记(2)

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

iOS 安装cocoapds

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

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

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

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

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

锐捷EWEB网管系统RCE漏洞

文章目录 免责声明漏洞描述漏洞原理影响版本漏洞复现修复建议 免责声明 该文章只为学习和交流,请不要做违法乱纪的事情,如有与本人无关 漏洞描述 锐捷网管系统是由北京锐捷数据时代科技有限公司开发的新一代基于云的网络管理软件,以"…

哈希表(unordered_set、unordered_map)

文章目录 一、unordered_set、unordered_map的介绍二、哈希表的建立方法2.1闭散列2.2开散列(哈希桶/拉链法) 三、闭散列代码(除留余数法)四、开散列代码(拉链法/哈希桶) 一、unordered_set、unordered_map的…

数据结构之——队列详解

目录 前言: 一、什么是队列 二、队列的实现 2.1 队列结构 2.2 队列初始化 2.3 队列销毁 2.4 入队列 2.5 出队列 2.6 获取队列头部元素 2.7 获取队列尾部元素 2.8 获取队列中有效元素个数 2.9 检测队列是否为空 三、 代码总览 Queue.h test.c 四、例题 前言…

树莓派、ubuntu低版本python3安装库

如果遇到树莓派中自带低版本python3,又不想额外去安装python3时,可能会遇到版本过低,无法安装库的情况,以下用我实际情况举例解决方案。 本次遇到的问题是树莓派低版本中,python3为3.7.3,需要安装numpy&am…

Python专题:八、列表(1)

Python的内置数据类型 数据类型:列表 list类型 可以是字符串,浮点数,整数,列表 列表特性 ①集合性的数据类型 ②列表是有序的 ③列表是可更新的 访问列表元素的方式也是[索引],也是从0开始的,不能超过…

EasyNmon服务器性能监控工具环境搭建

一、安装jdk环境 1、看我这篇博客 https://blog.csdn.net/weixin_54542209/article/details/138704468 二、下载最新easyNmon包 1、下载地址 https://github.com/mzky/easyNmon/releases wget https://github.com/mzky/easyNmon/releases/download/v1.9/easyNmon_AMD64.tar.…

Ansible-inventory和playbook

文章目录 一、inventory 主机清单1、列表表示2、inventory 中的变量3、变量3.1 主机变量3.2 组变量3.3 组嵌套 二、playbook剧本1、playbook的组成2、编写剧本2.1 剧本制作2.2 准备nginx.conf2.3 运行剧本2.4 查看webservers服务器2.5 补充参数 3、剧本定义、引用变量3.1 剧本制…

kdb 调试内核-延迟驱动加载

说明: 系统在启动过程中,一些要调试的驱动在 "进入kdb 之前" 就已经加载了, 那么,我们就需要延迟 "加载驱动" #define XX_module_platform_driver(__platform_driver) \XX_module_driver(__platform_driver, platform_d…

【Java】高效解决 非降序数组合并 两种方法

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! oj:https://leetcode.cn/problems/merge-sorted-array/submissions/ 合并两个有序数组是个经典问题,它不仅在算法学习中频繁出现,也在实际开发中经常遇到。合并数…

计算机毕业设计】springbootBBS论坛系统

本系统为用户而设计制作 BBS论坛系统,旨在实现BBS论坛智能化、现代化管理。本BBS论坛自动化系统的开发和研制的最终目的是将BBS论坛的运作模式从手工记录数据转变为网络信息查询管理,从而为现代管理人员的使用提供更多的便利和条件。使BBS论坛系统数字化…