29 String类
代表字符串。java中的所有字符串字面值(如“abc”)都作为此类的实例实现
1.String是一个final类,代表不可变的字符序列,不能被继承
2.字符串是常量,用双引号来表示,它们的值在创建之后不能更改
3.String实现了Serializable接口(可序列化):表示字符串是支持序列化的,通过网络的方式传给对方
实现了Comparable接口:表示String可以比较大小
4.String内部定义了 final char[] value 用于存储字符串数据
5.String 代表不可变的字符序列。简称:不可变性。
体现:1. 当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value赋值
2.当对现有的字符串进行连接操作时 也需要重新指定内存区域赋值,不能在原有的value赋值
String s3 = "abc";
s3 += "def";
System.out.println(s3);//abcdef
3.当调用String的replace()方法修改指定字符或字符串时,也必须重新指定内存区域赋值
String s1 = "abc";
String s2 = s1.replace('a', 'm');
System.out.println(s1);//abc
System.out.println(s2);//mbc
对字符串的内容进行任何的修改,在方法区(含字符串常量池)都必须重新指定内存区域赋值,原有的不变
6.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池
7.字符串常量池中是不会存储相同内容的字符串的
String对象的字符内容是存储在一个字符数组value[]中的
String的实例化方式
方式一:通过字面量定义的方式
方式二:通过new + 构造器的方式
//通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中
String s1 = "javaEE";
String s2 = "javaEE";
//通过new + 构造器的方式的方式:此时的s3和s4保存地址,是数据在堆空间中开辟空间以后对应的地址值
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(s1 == s4);//false
System.out.println(s3 == s4);//false 两个对象
equals一般比较地址值是否相同,但如果比较的是String类型的,会比较内容,因为String的equals重写过
(1) ==:比较的是两个字符串内存地址的数值是否相等,属于数值比较; (2)equals():比较的是两个字符串的内容,属于内容比较。
String不同拼接操作的对比
String s1 = "javaEE";
String s2 = "hadoop";
String s3 = "javaEEhadoop";
String s4 = "javaEE" + "hadoop";
String s5 = s1 + "hadoop";
String s6 = "javaEE" + s2;
String s7 = s1 + s2;
System.out.println(s3 == s4);//true
System.out.println(s3 == s5);//false
System.out.println(s3 == s6);//false
System.out.println(s3 == s7);//false
System.out.println(s5 == s6);//false
System.out.println(s5 == s7);//false
System.out.println(s6 == s7);//false
s8 = s5.intern();
System.out.println(s3 == s8);//true
常量与常量的拼接结果在常量池中,且常量池中不会存在相同内容的常量
只要其中有一个是变量,结果就在堆中
如果拼接的结果调用intern()方法,返回值就在常量池中
基本数据类型传的是数据
引用数据类型传的是地址
public class StringTest1 {
String str = new String("good");
char[] ch = {'t','e','s','t'};
public void change(String str,char ch[]){
str = "test ok";
ch[0] = 'b';
}
public static void main(String[] args) {
StringTest1 ex = new StringTest1();
ex.change(ex.str,ex.ch);
System.out.println(ex.str);//good
System.out.println(ex.ch);//best
}
}
堆
一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三部分:
Young Generate Space 新生区
Tenure generation space 养老区
Permanent space 永久存储区(永久区)(方法区)
虽然JVM规范将方法区描述为堆的一个逻辑部分,但它却还有一个别名叫Non-Heap(非堆)目的就是要和堆分开
String 常用方法1
int length()
: 返回字符串的长度:return value.length
String s1 = "HelloWorld";
System.out.println(s1.length());//10
char charAt(int index)
: 返回某索引处的字符return value[index]
String s1 = "HelloWorld";
System.out.println(s1.charAt(0));//H
boolean isEmpty())
:判断是否是空字符串:return value.length == 0
String s1 = "HelloWorld";
System.out.println(s1.isEmpty());//false
string toLowerCase()`: 使用默认语言环境,将String中的所有字符转换为小写
String s1 = "HelloWorld";
String s2 = s1.toLowerCase();
System.out.println(s1);//s1 不可变得 仍然为原来的字符串
System.out.println(s2);//helloworld 改成小写以后的字符串
string toUpperCase()
:使用默认语言环境,将String中的所有字符转换为大写
String trim()
:返回字符串的副本,忽略前导空白和尾部空白
用于输入用户名 qq号啥的
String s3 = " hello world ";
String s4 = s3.trim();
System.out.println(s4);
boolean equals(Object obj)
:比较字符串的内容是否相同
String s1 = "HelloWorld";
String s2 = "helloworld";
System.out.println(s1.equals(s2));//false
boolean equalsIgnoreCase(String anotherString)
: 与jequals方法类似,忽略大小写
String s1 = "HelloWorld";
String s2 = "helloworld";
System.out.println(s1.equalsIgnoreCase(s2));//true
String concat(String str)
:将指定字符串连接到此字符串的结尾。等价于用“+”
String s3 = "abc";
String s4 = s3.concat("ded");
System.out.println(s4);//abd=cdef
int compare To(String anotherString)
:比较两个字符串的大小
string substring(int beginIndex)
:返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
String s7 = "北京教育芜湖";
String s8 = s7.substring(2);
System.out.println(s7);
System.out.println(s8);//教育芜湖
string substring(int beginIndex, int endIndex)
:返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。左闭右开
String s9 = s7.substring(2, 4);
System.out.println(s9);//教育
String 常用方法2
boolean endsWith(String suffix
):测试此字符串是否以指定的后缀结束
String str1 = "HelloWorld";
boolean b1 = str1.endsWith("ld");
System.out.println(b1);//true
boolean startsWith(String prefix)
:测试此字符串是否以指定的前缀开始
String str1 = "HelloWorld";
boolean b2 = str1.startsWith("He");
System.out.println(b2);//false
boolean startsWith(String prefix,int toffset)
:测试此字符串从指定索引开始的子字符串是否以指定前缀开始
String str1 = "HelloWorld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);
boolean contains(CharSequence s)
:当且仅当此字符串包含指定的char值序列时,返回true
String str2 = "wo";
System.out.println(str1.contains(str2));//true
int indexOf(String str)
:返回指定子字符串在此字符串中第一次出现处的索引
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1
int indexOf(String str, int fromIndex)
:返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
System.out.println(str1.indexOf("lo",5));//-1
int lastIndexOf(String str)
:返回指定子字符串在此字符串中最右边出现处的索引
String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 从右向左找,但是数字还是从左开始数
int lastIndexOf(String str, int fromIndex)
:返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 注: indexOf和lastlndexOf方法如果未找到都是返回-1
String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4 从第6个开始往左
String常用方法3
string replace(char oldChar, char newChar)
:返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的。
String str1 = "北京清华北大北京";
String str2 = str1.replace('北', '南');
System.out.println(str2);//南京清华北大南京
string replace(CharSequence target,CharSequence replacement)
:使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
String str3 = str1.replace("北京", "上海");
System.out.println(str3);//上海清华北大上海
String replaceAll(String regex,String replacement)
:使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串。
String str = "12hello34world5java7891mysql456";
//把字符串中的数字替换成,如果结果中开头和结尾有,的话去掉
String string = str.replaceAll("\\d+",",").replaceAll("^,|,$","");
System.out.println(string);//hello,world,java,mysql
String replaceFirst(String regex,String replacement)
:使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串。
boolean matches(String regex)
:告知此字符串是否匹配给定的正则表达式。
String str = "12345";
//判断str字符串中是否全部有数字组成,即有1-n个数字组成
boolean matches = str.matches( regex: "lld+");
boolean matches = str.matches("\\d+");//正则
System.out.println(matches);//true
String tel = "0571-4534289";
//判断这是否是一个杭州的固定电话
boolean result = tel.matches( "0571-\\d{7,8}");
System.out.println(result);//true
String split(String regex)
:根据给定正则表达式的匹配拆分此字符串。
str = "hello|world|java";
String[] strs = str.split("\\|");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
System.out.println();
str2= "he11o.wor1d.java" ;
String[] strs2 = str2.split( "\\.");
for (int i = 0; i < strs2.length; i++) {
System.out.println(strs2[i]);
}
stringsplit(String regex, int limit)
:根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)