【JavaSE】(8) String 类

server/2025/1/23 10:38:22/

一、String 类常用方法

1、构造方法

        常用的这4种构造方法:直接法,或者传参字符串字面量、字符数组、字节数组。

        在 JDK1.8 中,String 类的字符串实际存储在 char 数组中:

        String 类也重写了 toString 方法,所以可以直接打印 String 类,打印效果就是字符串,而非 className@hashCode 的形式:

        可以看到源码中,重写的 toString 直接返回的 this,因为 this 本身就是字符串类,println 会对 String 类进行处理,打印出字符串:

        length() 方法可以获取字符串长度,这区别于数组通过属性 length 获取长度。

 2、字符串的比较(包含字符串常量池)

        在前面学习 equals 和 compareTo 方法时知道,直接使用 == 比较,比较的是对象的地址,而非对象的内容:

 

        但通过两种构造方式得到的 String 类,比较的结果却不同,它们存在区别:

  • 法1:① 字符串常量池不存在"hello"对象 >> 在常量池创建"hello"对象 >> 在堆上创建"hello"对象 >> 在栈上创建 s1 引用,存放堆上对象地址。② 字符串常量池存在"hello"对象 >> 直接在堆上创建"hello"对象 >> 在栈上创建 s2 引用,存放堆上对象地址。

  • 法2:① 字符串常量池不存在"hello"对象 >> 在常量池创建"hello"对象 >> 在栈上创建 s3 引用,存放常量池上对象地址。② 字符串常量池存在"hello"对象 >> 在栈上创建 s4 引用,存放常量池上对象地址。

        因此,法1得到 false,法2得到 true。由此可见,将频繁使用的字符串存到字符串常量池,能够提高性能减少内存开销。参考博客:深入理解Java字符串常量池 | 二哥的Java进阶之路

        如果想将 new String("hello") 也存放到字符串常量池中,可手动地使用 intern 方法

        回到比较,如果想比较对象的内容,使用 equals 和 compareTo 方法。还有 equalsIgnoreCase 和 compareToIgnoreCase 方法,可忽略字母大小写:

3、字符串查找

        查找失败时,除了 charAt 抛出异常,其它方法都是返回 -1。

4、字符串转换

(1) 整数、浮点数、布尔值、对象、数组 >> 字符串

(2)字符串 >> 整数、浮点数、数组

(3)大小写转换

(4)格式化转换

5、字符串替换

6、字符串拆分

注,正则表达式中:

  • *、+、| 有特殊含义,需要加上 "\\"。
  • \  在 java 中要用 "\\" 表示,在正则表达式中也有特殊含义,最后为"\\\\"。
  • 正则表达式中,| 表示连字符,可连接多个分隔符。

7、字符串截取

8、字符串的不可变性

        题外话:Java 中的引用就是 C语言指针的改版,存的是对象的地址,但是它更安全,因为只允许 = 和 . 操作(除了数组,还有[ ] 操作),所以简单又不易出错。

        从 String 类的注释中可以看到,字符串是常量,它的值不可修改:

        String 类的内容是怎么做到不可修改的呢?有人说是因为 final,但并不是:

        修饰类的 final 表示 String 类不可继承;修饰 value 的 final 表示这个数组引用不可修改,并不是引用指向的内容不可修改。

        value 引用指向的字符串内容不可修改的原因

  • value 数组由 private 修饰。
  • String 类没有向外部提供修改 value 指向的对象的方法。

        字符串不可修改的缺点:每次修改字符串其实是创建一个新的对象效率低

        字符串不可修改的优点:

  • 多线程中使用 String 类更安全。(线程以后学习)
  • 方便储存在常量池。如果常量池中的字符串可修改,则会造成多个引用的变化。
  • 方便将固定 hashCode 存储在哈希表中。(哈希表以后学习)

二、可修改的字符串(StringBuilder和StringBuffer)

  • String 不可修改字符串内容,而 StringBuilder 和 StringBuffer 可修改字符串内容。
  • StringBuilder 和 StringBuffer 的功能大致相同,最大的不同是:StringBuffer 提供了 synchronized 操作,能够保证线程安全。(详情以后学习)

1、String 和 StringBuilder 的对比以及 append 方法

        可以看到当需要频繁修改字符串时,使用 StringBuilder 的效率要高很多,因为它不需要频繁创建新的对象。每次 +=,都会将旧的 s 对象自动销毁,所以大的不是空间开销,而是创建对象的时间开销。

2、capacity 和 ensureCapacity

        当用 StringBuilder 创建可修改的字符串对象时,实际会申请比初始化的字符串更大的空间capacity 方法就是获取实际的空间大小

        当字符串容量不够时,StringBuilder 会自动扩容,有时为了防止频繁扩容造成时间开销的增加,会使用 ensureCapacity 提前手动设置好比较大的字符串容量

三、String 类练习题

1、387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

思路:统计每种字母的个数,找到第一个个数为 1 的字母。

java">class Solution {public int firstUniqChar(String s) {int[] cnt = new int[256];// 统计每种字符个数for(int i = 0; i < s.length(); i++)cnt[s.charAt(i)]++;// 找到第一个唯一的字符for(int i = 0; i < s.length(); i++)if(cnt[s.charAt(i)] == 1)return i;// 未找到return -1;}
}

2、字符串最后一个单词的长度_牛客题霸_牛客网

思路:找到最后一个空格位置,根据空格位置裁剪出最后一个单词,获取长度。

java">import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString s = in.nextLine();int index = s.lastIndexOf(' '); // 找到最后一个空格String lastWord = s.substring(index + 1, s.length()); // 裁剪出最后一个单词System.out.println(lastWord.length());}}
}

3、125. 验证回文串 - 力扣(LeetCode)

 

思路:先大写转小写,前、后设置一个标记移动,跳过非字母数字字符,匹配。

java">class Solution {// 判断小写字母和数字public boolean isValidChar(char ch) {if((ch >= 'a' && ch <='z') || (ch >= '0' && ch <= '9'))return true;elsereturn false;}public boolean isPalindrome(String s) {// 大写转小写s = s.toLowerCase();int i = 0, j = s.length() - 1;// 前、后移动while(i < j){// 前、后跳过所有其它字符,直到遇到小写字母和数字停止while(!isValidChar(s.charAt(i)) && i < j) i++;while(!isValidChar(s.charAt(j)) && i < j) j--;// 存在不匹配,则否if(s.charAt(i) != s.charAt(j)) return false;// 匹配,则更新i、ji++;j--;}return true;}
}

四、补充 -- FittenCode 插件

        它是一个AI功能,可以预测你要写的代码,还能根据项目的内容对它提问


http://www.ppmy.cn/server/160708.html

相关文章

JavaScript —— 判断语句与循环语句

判断语句 JavaScript中的if-else语句与C、Python、Java中类似。 直接输出到控制台&#xff1a; test.html中的内容为&#xff1a; <script type"module">let score 90;if (score > 85) {console.log("A");} else if (score > 70) {console…

云计算架构学习之LNMP架构部署、架构拆分、负载均衡-会话保持

一.LNMP架构部署 1.1. LNMP服务搭建 1.磁盘信息 2.内存 3.负载信息 4.Nginx你们公司都用来干嘛 5.文件句柄(文件描述符 打开文件最大数量) 6.你处理过系统中的漏洞吗 SSH漏洞 7.你写过什么shell脚本 8.监控通过什么告警 zabbix 具体监控哪些内容 9.mysql redis查询 你好H…

ChatGPT是强人工智能吗?

ChatGPT是强人工智能吗? 本文从人工智能发展的三个阶段的角度,分析当前强大的AI大模型所处的阶段,并通过对比各阶段的定义,明确各阶段的特点和未来发展方向; Narrow AI&#xff08;弱人工智能&#xff09;、AGI&#xff08;人工通用智能&#xff09;和 ASI&#xff08;人工超级…

跨域cookie携带问题总结

背景 我们知道很多场景&#xff0c;都需要前端请求带上cookie&#xff0c;例如用户鉴权、登陆校验等。而有些场景下&#xff0c;我们会发现请求不会带上cookie&#xff0c;这是为什么呢&#xff1f; 概念 cookie是种在域名下的信息。只有请求同域且同站的请求&#xff0c;才…

VBA语言的安全开发

VBA语言的安全开发 在当今信息化迅猛发展的时代&#xff0c;数据安全和信息保护显得尤为重要。VBA&#xff08;Visual Basic for Applications&#xff09;作为一种广泛应用于Microsoft Office系列软件的编程语言&#xff0c;因其简易性和强大功能&#xff0c;成为了众多企业和…

Ubuntu20.04 安装 cartographer

刚装完&#xff0c;赶紧记录下来&#xff01;——2025.1.22 官方网页&#xff1a; Compiling Cartographer ROS — Cartographer ROS documentation Building & Installation In order to build Cartographer ROS, we recommend using wstool and rosdep. For faster b…

HTML 元素详解:从入门到精通

HTML&#xff08;HyperText Markup Language&#xff09;是构建网页的基础语言&#xff0c;而 HTML 元素则是构成网页的基本单位。无论是网页的结构、内容还是样式&#xff0c;都离不开 HTML 元素。本文将深入探讨 HTML 元素的概念、结构、属性以及常见的使用方法&#xff0c;帮…

研究 Day.js 及其在 Vue3 和 Vue 框架中的应用详解

前言 在前端开发中&#xff0c;日期和时间处理是一个常见需求。随着技术的发展&#xff0c;我们有了更多高效、灵活的日期库可供选择。Day.js 就是一个轻量级、易于使用的 JavaScript 日期库&#xff0c;其灵感来源于 Moment.js&#xff0c;但体积更小&#xff0c;速度更快。本…