【Java】java.lang.String类的使用
1.String类概述
- 该类声明为final,不可被继承。
- 实现了
Serializable
接口,表示字符串是支持序列化的。 - 实现了
Comparabl
e接口,表示String可以比较大小。 - 内部定义了
final char[] value;
数组用于存储字符串的数据。 - 通过字面量的方式创建实例(
String str = "abc"
),此时的字符串值声明在字符串常量池中。 - 字符串常量池中是不会存储相同内容的字符串的。可以使用String类的equals()比较。
2.String类的不可变性
以下几种情况需要重新指定内存区域赋值,不能使用原有的value进行赋值
- 当对字符串重新赋值时。
- 当对现有的字符串进行连接操作时。
- 当调用String的replace()方法修改指定字符或字符串时。
String s1 = "abc"; String s2 = "abc"; s1 = "hello";
- 比较地址值,重新赋值后不相等
String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); //true s1 = "hello"; System.out.println(s1 == s2); //false
- 字符串连接后地址值不相等
String s3 = "abc"; s3+="def"; System.out.println(s2==s3); //false
- 使用replace方法后地址值不相等
String s4 = "abc"; String s5 = s4.replace('a','m'); System.out.println(s4==s5); //false
3.String实例化的不同方式
这两种方式的区别,字符串常量存储在字符串常量池,字符串对象存储在堆中。
String str1 = "abc"; String str2 = new String("abc");
s1和s2的数据"javaEE"声明在方法区中的字符串常量池中,s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
String s1 = "javaEE"; String s2 = "javaEE"; String s3 = new String("javaEE"); String s4 = new String("javaEE"); System.out.println(s1==s2); //true System.out.println(s1==s3); //false System.out.println(s3==s4); //false
4.字符串拼接和赋值对比
总结
- 常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量。
- 只要其中一个是变量,结果就在堆中。
- 如果拼接的结果调用intern()方法,返回值就在常量池中。
常量与常量拼接
String s3 = "javaEEhadoop"; String s4 = "javaEE"+"hadoop"; System.out.println(s3==s4); //true final String f4 = "javaEE";//s4:常量 String f5 = s4 + "hadoop"; System.out.println(f4 == f5);//true
存在变量
String a = "javaEEE"; String b = "hadoop"; String s5 = a+"hadoop"; String s6 = "javaEE"+b; String s7 = a+b; System.out.println(s3==s5); //false System.out.println(s6==s7); //false
调用了intern()
String s8 = s6.intern(); System.out.println(s3==s8); //true
String类中的intern()方法:调用这个方法之后把字符串对象加入常量池中
5.String类常用方法
(1)第一波
方法 | 描述 |
---|---|
int length() |
返回字符串的长度 return value.length |
char charAt(int index) |
返回某索引处的字符 return value[index] |
boolean isEmpty() |
判断是否是空字符串 return value.length==0 |
String toLowerCase() |
将所有字符转为小写 |
String toUpperCase() |
将所有字符转为大写 |
String trim() |
返回去除前后空格(空白)的字符串 |
boolean equals(Object obj) |
比较字符串的内容是否相同 |
String concat(String str) |
将指定字符串连接到此字符串的结尾,等价于用“+” |
int compareTo(String anotherString) |
比较两个字符串的大小 |
(2)第二波
方法 | 描述 |
---|---|
String substring(int beginIndex) |
返回从beginIndex开始截取到最后的字符串 |
String substring(int beginIndex,int endIndex) |
返回从beginIndex开始截取到endIndex(不包含)的字符串,[beginIndex,endIndex) |
boolean endsWith(String suffix) |
字符串是否以指定的后缀结束 |
boolean startsWith(String prefix,int toffset) |
字符串从指定索引开始的子字符串是否以指定前缀开始 |
boolean contains(CharSequence s) |
当且仅当此字符串包含指定的char值序列时,返回true |
int indexOf(String str) |
返回指定子字符串在此字符串中第一次出现处的索引 |
int indexOf(String str,int fromIndex) |
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始 |
int lastIndexOf(String str) |
返回指定子字符串在此字符串中最右边出现处的索引 |
int lastIndexOf(String str,int fromIndex) |
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 |
注:indexOf和lastIndexOf方法如果未找到都是返回-1
(3)第三波
方法 | 描述 |
---|---|
String replace(char oldChar,char newChar) |
使用newChar替换字符串中出现的所有oldChar并返回 |
String replace(CharSequence target,CharSequence replacement) |
使用replacement替换所有target,从左到右 |
String replaceAll(String regex,String replacement) |
使用给定的replacement替换此字符串满足正则表达式的子字符串 |
String replaceFirst(String regex,String replacement) |
使用给定的replacement替换满足正则表达式的第一个子字符串 |
boolean matches(String regex) |
告知此字符串是否匹配给定的正则表达式 |
String [] split(String regex) |
根据给定正则表达式的匹配拆分此字符串 |
String[] split(String regex,int limit) |
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中 |
6.String类与其他数据类型、结构的装换
(1)与基本数据类型、包装类之间的转换
- String --> 基本数据类型、包装类:调用包装类的静态方法 parseXX(str)
- 基本数据类型、包装类 --> String:调用String重载的valueOf(num) 或使用连接符
int num = Integer.parseInt(str1); String str2 = String.valueOf(num); String str3 = num + "";
(2)与字符数组之间的转换
- String --> char[]:调用String类的toCharArray()方法
- char[] --> String:调用String类的构造器
String str1 = "abc123"; char[] charArr = str1.toCharArray(); char[] arr = new char[]{'h','e','l','l','o'}; String str2 = new String(arr);
(3)与字节数组之间的转换
-
编码:字符串 --> 字节(看得懂 --> 看不懂的二进制数据)
- String --> byte[]:调用String的getBytes()方法
-
解码:字节 --> 字符串(看不懂的二进制数据 -->看得懂)
- byte[] --> String:调用String的构造器
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
String str1 = "abc123张三"; byte[] bytes = str1.getBytes(); //使用默认字符集进行编码 byte[] bytes2 = str1.getBytes("gbk"); //使用gbk字符集进行编码 String str2 = new String(bytes); //使用默认字符集进行解码 String str3 = new String(bytes2,"gbk"); String str4 = new String(bytes2); //出现乱码,编码集和解码集不一致
(4)与StringBuffer、StringBuilder之间的转换
- String --> StringBuffer、StringBuilder:调用StringBuffer、StringBuilder构造器
- StringBuffer、StringBuilder --> String:调用String构造器或StringBuffer、StringBuilder的toString()
7.JVM中字符串常量池存放位置
- jdk 1.6:字符串常量池存储在方法区(永久区)
- jdk 1.7:字符串常量池存储在堆空间
- jdk 1.8:字符串常量池存储在方法区(元空间)
8.String类常见题目
-
String str1 = new String("abc");
在内存中创建了几个对象?
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据"abc"。 -
模拟一个trim方法,去除字符串两端的空格。
-
将一个字符串进行反转;将字符串中指定部分进行反转(如:"abcdefg"反转为"abfedcg")
-
获取两个字符串中最大相同子串,如:str1 = "abcwerthelloyuiodef"; str2 = "cvhellobnm";
提示:将短的那个串进行长度依次递减的子串与较长的串比较。
- 对字符串进行自然顺序排序。
提示:①字符串变成字符数组。②对数组进行排序(冒泡,Arrays.sort())。③将排序后的数组变成字符串。
参考链接
1.Java String类中的intern()方法
2.String replace(CharSequence target, CharSequence replacement)
3.初探JDK源码之默认字符集
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY