0


String类 --- 上篇

文章目录

String类

前言: 本文主要内容

1.了解 String 常用的 方法

2.了解 字符串常量池

3.知道 String 和 StringBuider 和StringBuffer 的 区别

1.String常用的方法

1.1字符串构造

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

第一种: 使用 常量串 构造

在这里插入图片描述

第二种:直接new String对象

在这里插入图片描述

第三种:使用字符数组进行构造

在这里插入图片描述

补充: 通过这种方法我们 可以 指定范围 构造 字符串

在这里插入图片描述

字符串构造 看完 下面继续 看看 其他方法。

1.2 获取 字符串索引 出的字符 CharAt()

方法功能char charAt(int index)返回index位置上字符,如果index为负数或者越界,
抛出IndexOutOfBoundsException异常
在这里插入图片描述

1.3 将字符串转换为字符数组 toCharArray()

在这里插入图片描述

补充 一个 : Character 中 isDigit() 方法 ,判断 当前字符是否 为 数字 字符

题目: 给定字符串一个字符串, 判断其是否全部由数字所组成.

思路: 将字符串变为字符数组而后判断每一位字符是否是" 0 “~”‘9’"之间的内容,如果是则为数字

方法 一 : 使用 Character.isDigit() 方法 。

在这里插入图片描述

方法二 : 如果我们 忘记了 这个 方法,也可以不使用 方法, 我们 只需要保证 当前字符 在 “1” — “9” 之间 即可。

在这里插入图片描述

1.4 字符串比较

​ 1. == 比较是否引用 同一个 对象

注意:对于内置类型,比较的是变量中的值;对于引用类型比较的是引用中的地址。

问 : 下面 输出啥 :

在这里插入图片描述

A : true true true B: true true false

答案揭晓:

在这里插入图片描述

这里 就涉及到我们 字符串常量池 的 知识 : 这里 就 来 简单 的 了解 一下

在这里插入图片描述

下面就来看一下 是如何 存入 到字符串常量池中 注意: 这里是 一份草图 , 还不是 真正的 存储的过程。

在这里插入图片描述

此时 我们 的 str1 == str2 返回 true 也就不难理解 了 , 我们 == 比较的 是对象地址,那么 这里 都是 0x89 当然 返回 true。

那么 为啥 str1 == str3 返回 false 呢?

继续看图:

在这里插入图片描述

此时我们 str1 中的 地址 为 0x89 而 str3 中 的 地址 为 0x33 ,通过 == 比较地址 当然 是 不一样的 返回 false

看完了 草图 下面就来 画一个真正的 图

草图 相比 下面这个 图 就少了 我们的 哈希表, 和 链表 。

在这里插入图片描述

相信 通过 这 几幅图 我们 就能 很好的 了解 == 比较的规则 另外 : 还 初步 了解 字符串常量池。

下面 我们就来学习 第二种 ,真假比较

2.真假比较 equals()

使用 等号 只能 比较 我们的 地址,那么我们不管地址 只要内容 相等 就返回 true 不相等 就返回 false 即可 , 此时我们就可以 使用我们的

equals

在这里插入图片描述

我们也可 稍微看一下

equals

的 源码 , 你会 发现 他的 实现 方法 也不难。

在这里插入图片描述

instanceof 先 暂且理解为 同一种类型

  1. 先判断 长度
  2. 长度一样,通过 循环一个一个比较 ,不一样返回false

补充 : 这里我们 还能 通过 equalsIgnoreCase 忽略大小写 进行 比较

在这里插入图片描述

第三种 : 就是 我们的 大小比较

我们 进行 对象比较 需要 实现 Comparable 然后 重写 compareTo() , 在 接口 那篇博客中我们提到过 , 那时 我们 进入 String 源码 发现他 重写 了 compareTo() 方法,所以我们就可以 通过 compareTo完成我们的 对象比较。

下面就来 在看一遍 , 加深 一下 印象 。

1.String 实现了 Comparator 接口

在这里插入图片描述

2.重写 compareTo方法

在这里插入图片描述

下面就来使用一下 。

在这里插入图片描述

结果大于0,说明字符串A 比 字符串B 要大 结果小于0,

说明字符串A 比 字符串B 要小

结果等于0,说明字符串A 比 字符串B 相等

这里 我们比较的 是每个字符的 ASCII值 ,看 重写的 compareTo方法 也能知道。

在这里插入图片描述

补充: int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较

在这里插入图片描述

自此我们 字符串比较 就学玩了, 下面开始我们字符串查找

1.5 字符串查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:
方法功能char charAt(int index)返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常int indexOf(int ch)返回ch第一次出现的位置,没有返回-1int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1int indexOf(String str)返回str第一次出现的位置,没有返回-1int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1int lastIndexOf(int ch, intfromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1int lastIndexOf(String str)从后往前找,返回str第一次出现的位置,没有返回-1int lastIndexOf(String str, intfromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1
charAt 在上面 已经提过 ,这里 就不重复演示。

方法 一 : int indexOf(int ch)
方法功能int indexOf(int ch)返回ch第一次出现的位置,没有返回-1

方法演示:

在这里插入图片描述

方法二 :int indexOf(int ch, intfromIndex)
方法功能int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1

方法演示:

在这里插入图片描述

第一次 使用

indexOf

就 从3 下标开始找 ,找到 第一次 出现 的 ‘c’ , 返回 5,

第二次使用

 indexOf

从 6下标开始找,发现没有字符 ‘c’ , 返回 -1

方法三 : int indexOf(String str)
方法功能int indexOf(String str)返回str第一次出现的位置,没有返回-1

方法演示:
在这里插入图片描述

这里 我们同样可以指定位置 开始查找

方法四 : int indexOf(String str, int
fromIndex)
方法功能int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1
在这里插入图片描述

看完上面的 四种方法 ,你能想到什么 ?

这上面的 四种方法 构成了我们的 方法 的 重载, 稍微 复习一下 重载的 概念 : 方法名相同, 返回值不做要求, 参数列表不同(顺序,个数,数据类型 ) 。

注意: 在同一个类 或 不同类 中 都能构成重载,另外 重载 是 没有权限要求的。

方法五 :int lastIndexOf(int ch)
方法功能int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1
方法 演示: 上面 我们的 参数 是 int 类型, 不要急,字符串的本质是ASCII值 ,所以 是 可以 传 字符的。

在这里插入图片描述

在这里插入图片描述

方法六 : int lastIndexOf(int ch, int
fromIndex)
11int lastIndexOf(int ch, int fromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1

方法演示:
在这里插入图片描述

方法解释 :

在这里插入图片描述

方法 七 : int lastIndexOf(String str)

这里 就与上面的 方法 构成重载, 参数变为了 字符串, 那么 功能就是找子字符串
方法功能int lastIndexOf(String str)从后往前找,返回str第一次出现的位置,没有返回-1

方法演示:

在这里插入图片描述

方法八 : int lastIndexOf(String str, int
fromIndex)
方法功能int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1

方法演示:

在这里插入图片描述

方法九 : boolean contains(CharSequence s )
方法功能boolean contains(CharSequence s )判断子字符串是否存在

方法演示:

在这里插入图片描述

看完方法演示: 是不是 会有一个 疑问 ,为什么 contains 参数 类型 是

CharSequence

为啥 能 直接 传入 一个

 String

类型 的参数 呢 ?

下面就来 观察一下 源码 、
在这里插入图片描述

补: 这 里 传入 String 类型 就会 发生向上转型, 属于 向上转型的 第二种 , 传参。

1.6 转换

valueOf

将 对应 参数 转换为 我们的 String类型

在这里插入图片描述

方法使用:

1.将布尔类型 通过

valueOf

转化为 我们的 String 类

在这里插入图片描述

  1. 将 字符类型 转化为 字符串类型
    在这里插入图片描述

3.将字符数组 转化为 字符串类型

在这里插入图片描述

4.指定 范围 将字符数组转化为 字符串

在这里插入图片描述

5.将 int 类型 数据 转化为 字符串

在这里插入图片描述

这里 同样是 可以 转化 其他 类型 ,如 long 和 double ,最后 来看我们的 自定义类型。

6.将自定义类型, 转化为 字符串 类型

classStudent{publicString name;publicint age;publicvoideat(){System.out.println(name +"嗷嗷猛炫");}publicStudent(String name,int age){this.name = name;this.age = age;}@OverridepublicStringtoString(){return"Student{"+"name='"+ name +'\''+", age="+ age +'}';}}publicclassMain{publicstaticvoidmain(String[] args){String str =String.valueOf(newStudent("小黑",19));System.out.println(str);}}

在这里插入图片描述

这里 我们 各种类型 转化为 字符串 就 完成 了 , 就 一个 方法

valueOf

构成 方法 重载。

1.7 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
方法功能String replaceAll(String regex, String replacement)替换所有的指定内容String replaceFirst(String regex, String replacement)替换 首个内容

方法演示:

1.String replaceAll(String regex, String replacement) 替换 所有 的指定内容

在这里插入图片描述

可以 很明显 看到 我们的

abc

全部 替换成 了 我们的

fff
  1. String replaceFirst(String regex, String replacement) 替换 首个内容

在这里插入图片描述

注意 事项:由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

在这里插入图片描述

这里 我们 replaceFirst 重新 new 了 一个 StringBuffer 类型 , 最后 通过 toString 转为 我们的String 类型, 总的来说 还是 创建 了 新的 字符串

在这里插入图片描述

1.8 字符串拆分

将一个完整的字符串按照规定的分隔符分为若干个子字符串。

为什么 要学 字符串拆分 呢?

在这里插入图片描述

看到我们上面这个 百度网站 吗 ? 如果 我们想要拿到 上面的 信息 ,就可 使用 字串拆分 来 获取 , 下面 来看 一下 常用的方法。

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

方法 一 :String[] split(String regex) 将字符串全部拆分

在这里插入图片描述

下面 我们就 来 通过 等号 继续分割 。
在这里插入图片描述

方法二 :String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组

简单 来说 就是 部分拆分 ,

在这里插入图片描述

这里我们 按照 空格分割 , 指定了 2 说明 就 需要分 两组 即可 , 这里 从前 到 后找到了 第一个空格 处 ,进行分割 ,此时 正好分割成两部分 。

注意: 拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.

下面就来学习 一下 使用 split 方法 的 注意事项

先来看一段 代码
在这里插入图片描述

除了 逗号 我们还需要 注意下面这些 特殊的 字符

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

2.而如果是 \,那么就得写成 \ \ \ \ .

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

补充: 多次拆分

还是 拿

name=zhangsan&age=18

举例, 上面我们是 通过 两次拆分 第一次 使用 split(“&”) , 然后在此基础上, 在使用split(“=”) 完成第二次拆分, 其实 我们可以

通过 一个 split() 方法就完成 , 这 我们 只需要 通过

|

将 要拆分的 合在一起即可 如: split(“&|=”) 这样就完成了我们的 多次拆分

在这里插入图片描述

1.9 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下 :
方法功能String substring(int beginIndex)从指定索引截取到结尾String substring(int beginIndex, int endIndex)截取部分内容
方法 演示:

方法一: String substring(int beginIndex) 从指定索引截取到结尾

在这里插入图片描述

可以看到我们 str2 从 2 下标 一直截取到了 最后一个下标, 如果我们 从 0下标 截取, 就没啥意义 本身 从零 下标开始截取 , 截取到 最后一个下标,不就是 原来的数组吗 ? 所以 输入 0 是 没啥意义的操作, 这里 编译器的 substring 是 灰色 的也验证了。 另外 : 这里 从零 开始截取是不会参数 新 的 对象的 。

这里我们进入 substring 的源码 ,能看到 当 beginIndex == 0 的 时候 , 返回的 是 this 当前对象

在这里插入图片描述

方法二 :String substring(int beginIndex, int endIndex) 截取部分内容

这里 的 部分内容是 beginlndex 到 endlndex 的 内容

在这里插入图片描述

注意: substring(a,b) 的 截取是 左闭右开的

在这里插入图片描述

最后来看一下其他常用的 方法

2.0 其他操作方法

方法功能String trim()去掉字符串中的左右空格,保留中间空格String toUpperCase()字符串转大写String toLowerCase()字符串转小写boolean isEmpty()判断字符串是否是空的

方法演示:

方法一: Strng trim() 去掉字符串中的左右空格,保留中间空格

在这里插入图片描述

方法二 :String toUpperCase() 字符串转大写

在这里插入图片描述

方法三 : String toLowerCase() 字符串 转小写

在这里插入图片描述

注意: 上面只说了不针对 汉字, 其实这两个 大小转换的方法只会 针对 字母 像那些 符号同样也是不会 针对的

方法四: boolean isEmpty() 判断字符串是否是空的

在这里插入图片描述

到此 我们的字符串 常用的 方法 就 演示 完 了, 个人建议 这些不用死计 , 用的时候查即可 , 主要记住几个常用的 ,如 :

 charAt, toCharArray ,split, substring 等

下面就来 学习 一下我们的字符串 常量池

字符串常量池

先来看一段代码:

publicstaticvoidmain(String[] args){String s1 ="hello";String s2 ="hello";String s3 =newString("hello");String s4 =newString("hello");System.out.println(s1 == s2);System.out.println(s1 == s3);System.out.println(s3 == s4);}

刚刚我们在字符串比较 哪里 稍微 画了 一下 草图, 这里 你能不能 说出 这个程序 输出 了什么 吗 ?

答案揭晓:
在这里插入图片描述

这里我们 还是 在 来 画一遍 草图, 加深 一下 我们的 印象 , (注意: 这里 草图并不会意向 我们 对 结果的判断 , 另外 池 会在 我们学习 jvm 时 ,更加深入 的 学习)。

在这里插入图片描述

此时 我们就 很容易得到答案 ,

这里我们就来 知道一下为啥要有池的 :

在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。

“池” 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 “内存池”, “线程池”, “数据库连接池” …

比如:家里给大家打生活费的方式

  1. 家里经济拮据,每月定时打生活费,有时可能会晚,最差情况下可能需要向家里张口要,速度慢
  2. 家里有矿,一次性打一年的生活费放到银行卡中,自己随用随取,速度非常快

方式2,就是池化技术的一种示例,钱放在卡上,随用随取,效率非常高。常见的池化技术比如:数据库连接池、线程池等

另外 : 除了字符串常量池 , 还有 Class文件常量池 ,运行时常量池 , 这里我们简单看一下概念, 后面 会在jvm 中 具体 讲到

  1. Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息

2.运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份

字符串常量池

下面就来看几道例题 : 加深一下 印象

题目 一 : 请问 一下代码输出什么 ?

在这里插入图片描述

A true B false C 钝角

答案揭晓 :

在这里插入图片描述

== 号 两边的是引用数据类型,那么比较的是"地址相不相同"。“admin”,存放在常量池当中,但是通过方法,userId.toLowerCase()。返回的是一个新的对象,

大家可以看看该方法的源码。最终的返回值是:return new String(形参…); 并不是常量池的"admin"。所以,这里比较的结果就是false。

题目二:请问下面代码输出了什么? 

在这里插入图片描述

答 :

第一步: 我们的 “abc” + “def” 会 在编译时变成 成 “abcdef” (因为 “abc” 和"def" 是常量 )

第二步: new String(s1) 会产生 新的对象,所以这里 等号 的if 语句就不会进入,输出 第 4 行

图解 :

img

通过 字节码文件 观察 abc + def 在编译时 变成 abcdef

在这里插入图片描述

intern() 手动入池

题目三 : 问 下面的代码 输出 什么 ?

在这里插入图片描述

此时我们 看到 上面代码中 出现了 一个 intern 方法, 我们还没有 学, 这里就来讲解一下 ,

intern方法

概念:

intern

是一个``native`方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手
动将创建的String对象添加到常量池中。

啥意思呢 ? 下面就来通过图 来 了解 一下

这里我们先将 s1.intern 注释 , 先来了解 一下没有 intern 方法 的 图
在这里插入图片描述

然后我们将 intern 方法 放开

在这里插入图片描述

下面我们就来改造一下上面的 代码 ,在分析一下 结果 。

问 : 下面输出 什么 ?
在这里插入图片描述

A: true B: false C:钝角

图解:
在这里插入图片描述

通过 图 分析 答案就显而易见 了 ,为 false

下面我们来 针对 我们上面 所有 画的 图 来 完成 一道练习题 。

请问: 下面 三种 String 类 对象实例化,分别 会创建出几个 对象 (前提 : 常量池都不存在当前对象)

1.String str = “hello”

2.String str = new String(“hello”)

String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’})

答案揭晓:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

所以 答案 为

2 3 3

这里就先讲到这里, 篇幅过长, 剩下内容, 在 下文中 继续。

下文预告 : String类 下篇

标签: java 开发语言

本文转载自: https://blog.csdn.net/mu_tong_/article/details/126341309
版权归原作者 牧.. 所有, 如有侵权,请联系我们删除。

“String类 --- 上篇”的评论:

还没有评论