Java-String类

字符串这个词我想同学们并不陌生,但Java语言中的字符串和我们之前所学习的C语言字符串,差别可谓是非常之大,因为在C语言当中,想要表示一个字符串,就只能使用字符数组或字符指针,但是这种" 对数据进行细致的操作 " 和 " 将操作数据与方法分开 "的方式,并不符合我们Java的" 面向对象思想 ",于是Java语言提供了专门的String类:

一、String的常用方法

① 字符串构造

📚 ++关于字符串的构造,常用的有以下三种++:

1. 使用常量字符串构造
2. new String对象
3. 使用字符数组进行构造

📖 虽然构造方式众多,但同样也是有区别的:

4. 构造方式的区别

📕 当我们使用第一种方法:"使用常量字符串构造" 时,我们创建出来的字符串是在"常量池"中的,而当我们创建出第一个字符串后,再创建内容相同的第二个字符串时,就会从之前在"常量池"中查找之前使用过的"常量字符串",如果能查找到,就会直接使用这个常量字符串,并且不会再创建新的常量字符串,找不到则反之。

📌 图示

由此我们可以知道,s1和s2其实本质上是一样的:

📕 当我们使用第二种方法:" new String对象 "创建字符串时,创建的就是两个不同的字符串了~

使用new关键字构造出的字符串,不再是去"常量池"中寻找"常量字符串",而是在"堆内存"中存储,并且"每一次构造都会申请一个内存空间",所以当我们使用 new 创建两个"Hello World"时,代表两个字符串内容相同,但地址并不相同。

📌 图示:

由此我们可以知道,s1和s2其实本质上是不同的:

② 字符串的比较

📖 ++其实我们刚刚已经稍微了解到了字符串的比较,那么接下来让我们细致的讲解++:

1. " == "比较

用" == "比较字符串,比较直白地描述其实就是:比较两个字符串的"地址"是否相同。

" s == s0 "得到的是"true"是因为两者都是使用"常量池中的同一个位置的同一个字符串",故两者地址是相同的。

" s == s1 "得到的是"false"是因为s指代的是"常量池中的字符串",而s1指代的是"堆内存中的字符串",故两者地址不同。

" s1 == s2 "得到的是"false"是因为使用new创建字符串时,"每一次构造都会申请一个内存空间",故两者地址不同。

" s1 == s3 "得到的是"true"是因为s3 = s1时将地址也传了过去,于是两者地址相同。

2. "equals()"方法比较

用"equals()"方法比较字符串其实就是:对字符串中的内容进行比较

虽然这几个字符串的构造方式并不相同,但它们的内容都是相同的,所以当我们使用equals()进行比较时,显示出的反馈都是true~

但当我们使用equals()方法去比较自定义类型"People"时,即使他们的内容相同,我们得到的反馈却是false,这是为什么呢?

这是因为在编译器中,我们的equals()方法并没有自动配置出比较自定义类型的功能,如果我们想要使用equals()方法去比较自定义类型,就必须自己去对方法进行重写:

而我们全能的idea~已经帮我们自动配置好了"快捷重写equals()"的功能:

而当我们进入String里头去,就会发现:

我们的编译器已经自动写好了String的equals()方法~

3. compareTo()方法比较

compareTo()方法同样能比较两个字符串,而与equals()方法有所不同的是,compareTo()方法比较能够返回的类型是int,而非boolean,这同时也就代表着compareTo()方法是能够返回"正数,负数"的,也就代表着compareTo()方法在一些情况下能够比较两个字符串的大小关系~

我们可以看到,这时就能够通过返回值的大小,对字符串的大小进行比较了~

++compareTo()方法的比较规则++:

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

📕 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值

4. compareTolgnoreCase()比较

此方法与"compareTo"方法大同小异,唯一的区别只是,使用"compareTolgnoreCase"方法比较字符串时,会省略字母的大小写~

③ 字符串查找

1. charAt(int index)查找

📕 返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException异常

(返回的是索引,第一个字符是从0算起而非1)

2. indexOf()查找

📕 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 lastIndex(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;

📖 ++我们可以使用刚刚学习到的这几个查找方法,尝试去做一个小练习++:

练习:字符串中的第一个唯一字符

给定一个字符串 s ,找到它的第一个不重复的字符并返回它的索引 。如果不存在,则返回 -1

++示例++:

复制代码
输入: s = "leetcode"
输出: 0
输入: s = "loveleetcode"
输出: 2
输入: s = "aabb"
输出: -1

思路:我知道大家有思路,但是既然说是使用"字符的查找"来解题,那我们就不用大家心中的"创建数组,遍历字符串,出现字符对应数组下标+1"的这种做法啦~

++我们首先想一下++ :应该如何判断字符是否为字符串中的单一字符?

++单一字符肯定只会出现一次吧?而我们上面有两个方法++:

📕 int indexOf(int ch):返回ch第一次出现的位置

📕 int lastIndex(int ch):从后往前找,返回ch第一次出现的位置

而如果是单一字符,我们使用这两种方法进行查找,得到的位置肯定相同,而如果不是单一字符,第一次出现肯定小于第二次出现~

而题中说的是**"字符串第一个单一字符"** ,++我们就可以通过遍历字符串,进行查找++:

但是我们可以看到,此时这个代码所消耗的时间并不是很优,只超过了50%的人;如此我们可以进行一下改进:(遍历字符串过程中,如果有出现已出现过的字符,我们便跳过该字符)

如此,效率便大大提高啦~

④ 字符串的转化

1. 字符串与数值的转化

📕 ++其他类型转换成字符串++:

📕 ++字符串转换成其他类型++:

2. 大小写转换

📕 toUpperCase():将小写字符转换成大写字符;

(注意:String是不可修改的类型,所以使用这些转换操作时,都不是对本字符串进行的操作,而是创建出一个新字符串,并且需要使用一个字符串来接收)

📕 toLowerCase():将大写字符转换成小写字符;

3. 字符串转数组

📕 toCharArray():将字符串转换成由多个字符组成的char[]数组;

⑤ 字符串替换

1. replace

📕 将字符串中某个字符替换成新的字符:

2. replaceFirst

📕 将字符串中某个字符串第一次出现的位置替换成新字符串:

3. replaceAll

(这个方法非常重要,并且很多时候都能用得上,因为它不仅可以接收单一的字符或者字符串,它还可以接收[正则表达式]~)

📕 去除字符串中除了[a-zA-Z_0-9]以外的所有字符:

📕 去除字符串中除了[0-9]以外的所有字符:

📕可以按照自己想要的模式进行替换

比如:++把 hello world 中的 ' l ',' e ',' o '都替换成0++:

还有很多种不同的搭配,大家可以在学习了正则表达式之后自行测试~

⑥ 字符串拆分

📕 split(String regex):将字符串全部拆分

📕 split(String regex, int limit):将字符串拆分成limit组

⑦ 字符串截取

📕 substring(int beginIndex):从指定索引截取到结尾

📕 substring(int beginIndex, int endIndex):截取部分内容

我们再额外学习一个实用的小方法:

📕 trim():去掉字符串中的左右空格,保留中间空格

我们使用这个方法,结合以上的方法来尝试做一个小练习:

练习:最后一个单词的长度

📖 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。

单词 是指仅由字母组成、不包含任何空格字符的最大子字符串

想好了嘛?这题!其实我们只需要用一行!就能做出来~你敢信嘛?

其实很简单,首先使用trim()方法去除字符串两边的空格,然后使用split(" ")将字符串通过空格分隔开,最后获取该字符串数组的最后一位,取其长度返回就好啦~

二、StringBuilder和StringBuffer

因为String的字符串是无法进行修改的,因此在Java中也为我们适配了对应可以进行修改的字符串

① append方法

📕 append方法用于将一个字符串追加到现有的 StringBuilder 对象末尾

② insert方法

📕insert方法用于在指定位置插入字符串:

③ delete方法

📕 delete方法用于删除字符串中指定范围的子串:

④ reverse方法

📕 reverse方法用于反转字符串:

⑤ setLength方法

📕 用于设置字符串的长度,可能截断或补零:

练习:验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

📖 ++思路++:

📕 先使用"toLowerCase()方法"将字符串全部变成小写字符

📕然后使用"replaceAll()方法"将不是小写字符和不是数字的字符都删除

📕 然后我们创建一个"StringBuilder"对象来接收当前的s字符串

📕 我们对刚创建出的StringBuilder对象进行"reverse()"反转,然后再变成String型

📕 最后使用"equals()"方法判断反转后的字符串与反转前的字符串内容是否相等

📚 ++代码实现++:

(纯为了提高字符串方法使用的熟练度,补药在意用时...)

那么关于String类的相关知识,就为大家分享到这里啦,如果有什么讲的不清楚,或者不够准确的地方还请大家多多指出,我也会虚心改正的,那么我们下次再见啦~

相关推荐
草莓base3 分钟前
【手写一个spring】spring源码的简单实现--bean对象的创建
java·spring·rpc
legend_jz15 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
drebander27 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天24931 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn36 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
莫叫石榴姐36 分钟前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
程序猿阿伟37 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy1 小时前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书1 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子1 小时前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python