1.字符串的介绍
字符串是由双引号括号起来的多个字符例如:" hello" 、" 花朵"、"A"都是字符串
java是使用Unicode编码,Unicode编码包含中文等多个字符, 所以在java中使用由中文构成的字符串合法。
很多计算机语言提供了两种字符串,不可变字符串和可变字符串,它们之间的区别在于当字符串进行拼接等修改操作时,不可变字符串会创新新的字符串对象,而可变字符串不会创新对象
java SE提供了三个字符串类:String、StringBuffer、StringBuilder。String是不可变字符串。
StringBuffer和StringBuilder是可变字符串
注意:字符串有一个极端情况,就是 "" 表示的是空字符串,双引号中没有内容,空字符串不是NULL,空字符串是分配内存空间,而NULL是没有分配内存空间的。
2.不可变字符串
java中不可变字符串类是String,属于java.lang包,它也是java非常重要的类
创建String对象通过String对象构造方法实现,常用的构造方法如下:
String():使用空字符串创建并初始化一个新的String对象
String(String original):使用另外一个字符串创建并初始化一个新的String对象
注意:java.lang包中提供了很多java基础类,包括Object、Class、String和Math等基本类。在使用java.lang包中的类时不需要引入(import)该包,因为它是由解释器自动引入的。当然,引入java.lang包程序也不会有编译错误
String(StringBuffer buffer):使用可变字符串对象(StringBuffer)创建并初始化一个新的String对象
String(StringBuilder Builder):使用可变字符串对象(StringBuilder)创建并初始化一个新的String对象
String(byte[] bytes):使用平台的默认字符解码指定的byte数组,通过byte数组创建并初始化一个新的String对象
String(char[] value):通过字符数组创建并初始化一个新的String对象
String(char[] value,int offset,int count):通过字符数组的子数组创建并初始化一个新的String对象;office参数是子数组第一个字符的索引,count参数指定子数组的长度
创建字符串对象例题如下:
String s1 = new String();
String s2 = new String("hello");
String s3 = new String("\u0048\u0065\u006c\u006c\u006f");
System.out.println("s2=" + s2);
System.out.println("s3=" + s3);
char ch[] = {'a', 'b', 'c'};
String s4 = new String(ch);
String s5 = new String(ch, 1, 4);
System.out.println("s4=" + s4);
System.out.println("s5=" + s5);
byte by[] = {97, 98, 99};
String s6 = new String(by);
System.out.println("s6=" + s6);
System.out.println("s6字符串长度=" + s6.length());
结果是:
s2=hello
s3=hello
s4=abcde
s5=bcde
s6=abc
s6字符串长度=3
3.字符串的拼接
String字符串虽然是不可变字符串,但也可以进行拼接,只是会产生一个新的对象。String字符串拼接可以使用 ‘+’ 运算符或String的concat(String str)方法。‘+’运算符的优势是可以连接任何类型数据拼接成为字符串,而concat方法只能拼接String类型字符串
使用例子如下:
String s1="hello";
String s2= s1+' ';
String s3= s2+"world";
System.out.println(s3);
String s4="hello";
s4+=" ";
//运算符+,支持+=赋值字符串
System.out.println(s4);
String s5="hello";
//使用concat方法
s5=s5.concat(" ").concat("world");
System.out.println(s5);
java.util.Date now =new java.util.Date();
//对象拼接自动调用toString()方法
String s6="今天是:"+now;
System.out.println(s6);;
输出结果:
hello world
hello world
hello world
今天是:Tue Dec 19 19:55:08 CST 2023
使用+=运算符时本质上也是+运算符进行拼接
concat方法的参数和返回值都是String,所以可以连续调用该方法进行多个字符串的拼接
java中所有对象都有一个toString()方法,该方法可以将对象转换为字符串,拼接过程会调用该对象的toString()方法,将该对象转换为字符串后再进行拼接。java.util.Date类是java SE提供的日期类。作用是赋值给s6今天的时间,精准到秒,星期几和月份都是缩写。
4.字符串的查找
在给定的字符串中查找字符或字符串是比较常见的操作,在String类中提供了indexOF和lastIndexOF方法用于查找字符或字符串,返回值是查找的字符或字符串所在的位置,-1表示没有找到。这两种方法有多个重载版本
int indexOF(int ch):从前往后走搜索字符ch,返回第一次找到字符ch所在处的索引
int indexOF(int ch,int fromIndex):从指定的索引开始从前往后搜索字符ch,返回第一次找到字符ch所在的索引
int indexOF(String str):从前往后走搜索字符串str,返回第一次找到字符串str所在处的索引
int indexOF(String str,int fromIndex):从指定的索引开始从前往后搜索字符串str,返回第一次找到字符串str所在的索引
int lastIndexOF(int ch):从后往前走搜索字符ch,返回第一次找到字符ch所在处的索引
int lastIndexOF(int ch,int fromIndex):从指定的索引开始从后往前搜索字符ch,返回第一次找到字符ch所在的索引
int lastIndexOF(String str):从后往前走搜索字符串str,返回第一次找到字符串str所在处的索引
int lastIndexOF(String str,int fromIndex):从指定的索引开始从后往前搜索字符串str,返回第一次找到字符串str所在的索引
注意:字符串本质上是字符数组,因此它也有索引,索引从零开始String的charAt(int index)方法可以返回索引index所在的字符
例题如下:
String sourceStr ="There is a string accessing example.";
//获取字符串长度
int len =sourceStr.length();
//获取索引位置16的字符
char ch=sourceStr.charAt(16);
//查找字符和字符串
int firstchar1=sourceStr.indexOf('r');
int lastchar1=sourceStr.lastIndexOf('r');
int firstStr1=sourceStr.indexOf("ing");
int lastStr1=sourceStr.lastIndexOf("ing");
int firstchar2=sourceStr.indexOf('e',15);
int lastchar2=sourceStr.lastIndexOf('e',15);
int firstStr2=sourceStr.indexOf("ing",5);
int lastStr2=sourceStr.lastIndexOf("ing",5);
System.out.println("原始字符串:"+sourceStr);
System.out.println("字符串长度:"+len);
System.out.println("索引16的字符:"+ch);
System.out.println("从前往后搜索r的字符,第一次找到它所在索引:"+firstchar1);
System.out.println("从后往前搜索r的字符,第一次找到它所在索引:"+lastchar1);
System.out.println("从前往后搜索ing的字符串,第一次找到它所在索引:"+firstStr1);
System.out.println("从后往前搜索ing的字符串,第一次找到它所在索引:"+lastStr1);
System.out.println("从索引为15位置开始,从前往后搜索e字符,第一次找到它所在索引:"+firstchar2);
System.out.println("从索引为15位置开始,从后往前搜索e字符,第一次找到它所在索引:"+lastchar2);
System.out.println("从索引为5位置开始,从后往前搜索ing字符串,第一次找到它所索引:"+firstStr2);
System.out.println("从索引为5位置开始,从后往前搜索ing字符串,第一次找到它所在索引:"+lastStr2);
结果如下:
原始字符串:There is a string accessing example.
字符串长度:36
索引16的字符:g
从前往后搜索r的字符,第一次找到它所在索引:3
从后往前搜索r的字符,第一次找到它所在索引:13
从前往后搜索ing的字符串,第一次找到它所在索引:14
从后往前搜索ing的字符串,第一次找到它所在索引:24
从索引为15位置开始,从前往后搜索e字符,第一次找到它所在索引:21
从索引为15位置开始,从后往前搜索e字符,第一次找到它所在索引:4
从索引为5位置开始,从后往前搜索ing字符串,第一次找到它所在索引:14
从索引为5位置开始,从后往前搜索ing字符串,第一次找到它所在索引:-1
5.字符串比较
5.1比较相等
String提供的比较字符串相等的方法:
boolean equals(Object anObject):比较两个字符串中内容是否相等,不忽略大小写
boolean equalsIgnoreCase(String anotherString):比较两个字符串中内容是否相等,忽略大小写
5.2比较大小
String提供的比较大小的方法:
int compareTo(String anotherString):按照字典顺序比较两个字符串。如果参数字符串等于此字符串,则返回值0;如果此字符串小于参数字符串,则返回一个小于0的值;如果此字符串大于参数字符串,则返回一个大于0的值,不忽略大小写
int compareToIgnoreCase(String str):按照字典顺序比较两个字符串。如果参数字符串等于此字符串,则返回值0;如果此字符串小于参数字符串,则返回一个小于0的值;如果此字符串大于参数字符串,则返回一个大于0的值,忽略大小写
5.3比较前缀和后缀
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean strrtsWith(String suffix):测试此字符串是否以指定的前缀开始
字符串比较的事例如下:
String s1=new String("hello");
String s2=new String("hello");
//比较字符串是否是相同的引用
System.out.println("s1==s2:"+(s1==s2));
//比较字符串内容是否是相同
System.out.println("s1.equals(s2):"+(s1.equals(s2)));
String s3="HELLo";
//忽略大小写比较字符串内容是否是相同
System.out.println("s1.equalsIgnoreCase(s2):"+s1.equalsIgnoreCase(s2));
//比较大小
String s4="java";
String s5="Swift";
//比较字符串大小s4>s5
System.out.println("s4.compareTo(s5):"+(s4.compareTo(s5)));
//忽略大小写比较字符串大小s4<s5
System.out.println("s4.compareToIgnoreCase(s5):"+(s4.compareToIgnoreCase(s5)));
//判断文件名中文件名
String [] doc={"java.docx","JavaBean.docx","Objecitve-C.xlsx","Swift.docx"};
int word =0;
//查找文件夹中word文档个数
for(String wor:doc)
{
//去掉前后空格
wor=wor.trim();
//比较后缀是否有.docx字符串
if(wor.endsWith(".docx"))
{
word++;
}
}
System.out.println("文件夹中word文档的个数是:"+word);
int java=0;
//查找文件夹中java相关文档个数
for(String javac:doc)
{
//去掉前后空格
javac=javac.trim();
//全部字符转小写
javac=javac.toLowerCase();
//比较前缀是否有java字符串
if(javac.startsWith("java"))
{
java++;
}
}
System.out.println("文件夹中java相关文旦个数是:"+java);
结果如下:
s1==s2:false
s1.equals(s2):true
s1.equalsIgnoreCase(s2):true
s4.compareTo(s5):23
s4.compareToIgnoreCase(s5):-9
文件夹中word文档的个数是:3
文件夹中java相关文旦个数是:2
compareTo方法按照字典顺序比较两个字符串,字符在字典中的顺序是Unicode编码的顺序,compareToIgnoreCase方法是忽略大小写的,要么全部小写,要么全部大学,结果都是一样的
trim()方法是去除字符串的前后空格,toUpperCase()方法将字符串全部转换为大写字符串,toLowerCase()方法将字符串全部转换为小写字符串,
6.字符串截取
String提供的字符串截取的方法:
String substring(int beginIndex):从指定索引beginIndex开始截取到字符串结束
String substring(int beginIndex,int endIndex):从指定索引beginIndex开始截取直到索引endIndex -1处的字符,注意:包括索引为beginIndex处的字符,但不包括索引为endIndex处的字符
代码如下:
String sourceStr ="There is a string accessing example.";
//截取example.子字符串
String subStr1=sourceStr.substring(28);
//截取string子字符串
String subStr2=sourceStr.substring(11,17);
System.out.println("subStr1="+subStr1);
System.out.println("subStr2="+subStr2);
//使用split方法分隔字符串
System.out.println("使用split方法:");
String[] arr=sourceStr.split(" ");
for (String str:arr)
{
System.out.println(str);
}
结果如下:
subStr1=example.
subStr2=string
使用split方法:
There
is
a
string
accessing
example.
subStr1是从第28个字符开始到结束
subStr2是从第11个字符开始到第endIndex-1也就是16
split()方法的返回值是String[]类型
7.可变字符串
可变字符串在追加、删除、修改、插入和拼接等操作不会产生新的对象
7.1StringBuffer和StringBuilder
java提供了两个可变字符串类StringBuffer和StringBuilder,中文翻译成 “字符串缓冲区”
StringBuffer是线程安全的,它的方法是支持线程同步,线程同步会操作串行顺序执行,在单线程环境下会影响效率。StringBuilder是StringBuffer单线程版本,java5之后发布的,它不是线程安全的,但是它的执行效率高
StringBuffer和StringBuilder具有完全相同的API,即构造方法和普通方法等内容一样,StringBuilder中构造方法有4个
StringBuilder():创建字符串内容是空的StringBuilder对象,初始容量默认为16个字符
StringBuilder(CharSequence seq):指定CharSequence字符串创建StringBuilder对象。CharSequence接口类型,它的实现类有String、StringBuffer和StringBuilder等,所以参数seq可以是String、StringBuffer和StringBuilder等类型
StringBuilder(int capacity):创建字符串内容是空的StringBuilder对象,初始容量由参数capacity指定
StringBuilder(String str):指定String字符串创建StringBuilder对象
上面的方法也同样适用于StringBuffer类,效果是一样的
注意:字符串长度和字符串缓冲区容量区别。字符串长度是指字符串缓冲区中目前所包含的字符串长度,通过length()获得;字符串缓冲区容量是缓冲区中所容纳的最大字符数,通过capacity()获得,但所容纳的字符超过这个长度时,字符串缓冲区自动扩充容量,但这是以牺牲性能作为代价的扩容
代码如下:
StringBuilder sbuilder1 =new StringBuilder();
System.out.println("包含的字符串长度:"+sbuilder1.length());
System.out.println("字符串缓冲区容量:"+sbuilder1.capacity());
StringBuilder sbuilder2 = new StringBuilder("hello");
System.out.println("包含的字符串长度:"+sbuilder2.length());
System.out.println("字符串缓冲区容量:"+sbuilder2.capacity());
//字符串缓冲区初始容量是16,超过后会扩容
StringBuilder sbuilder3 =new StringBuilder();
for(int i=0;i<17;i++)
{
sbuilder3.append(8);
}
System.out.println("包含的字符串长度:"+sbuilder3.length());
System.out.println("字符串缓冲区容量:"+sbuilder3.capacity());
结果如下:
包含的字符串长度:0
字符串缓冲区容量:16
包含的字符串长度:5
字符串缓冲区容量:21
包含的字符串长度:17
字符串缓冲区容量:34
7.2字符串追加
StringBuilder提供了很多修改字符串缓冲区的方法,如追加、插入、删除、替换等
StringBuffer类追加方法是append()方法
append()方法有很多重载方法,可以追加任何类型数据
StringBuffer的追加方和StringBuilder一样
append()方法相当于 “+”,将指定的字符串追加到此字符序列
StringBuffer.append()追加的字符串在同一个内存地址
for(int i=0;i<17;i++)
{
sbuilder3.append(8);
}
sbuilder字符串是16个8
7.3字符串插入、删除和替换
StringBuilder中实现插入、删除和替换的方法如下:
StringBuilder insert(int offset,String str):在字符串缓冲区中引为offset的字符位置之前插入str,insert有很多重载方式,可以插入任何数据类型
StringBuilder delete(int start,int end):在字符串缓冲区中删除子字符串,要删除的子字符串从指定的索引start开始到索引end-1处的字符。start和end两个参数与substring(int beginIndex,int endIndex)方法的两个参数一样
StringBuilder replace(int start,int end,String str):在字符串缓冲区中用str替换子字符串,子字符串从指定索引start开始到索引end-1处的字符。start和end同delete(int start,int end)方法
代码如下:
String str1="java C";
//从不可变的字符串创建可变字符串对象
StringBuilder mstr=new StringBuilder(str1);
//插入字符串
mstr.insert(4," C++");
System.out.println(mstr);
//具有追加效果的插入字符串
mstr.insert(mstr.length()," Objective-C");
System.out.println(mstr);
//追加字符串
mstr.append(" and Swift");
System.out.println(mstr);
//删除字符串
mstr.delete(11,23);
System.out.println(mstr);
结果如下:
java C++ C
java C++ C Objective-C
java C++ C Objective-C and Swift
java C++ C and Swift