目录
例5.1 编写一段代码,声明多个字符串变量,用不同的赋值方法给这些字符串变量赋值并输出。
字符串是常量,是不可修改的。拼接两个字符串之后,原生的字符串不会发生变化,而是在内存中生成一个新的字符串。
例5.3 在项目中创建类Link,在主方法中创建数值型变量,实现将字符串与整型、浮点型变量相连的结果输出。
例5.5 创建字符串对象str,判断str中是否含有子字符串“abc”。
2.indexOf(String str,int fromIndex)
例5.6查找字符串“Weare the world”中“r”第一、二、三次出现的索引位置
3.public int lastIndexOf(String str)
例5.7 查找字符串“Let it go!Let it go”中单词“go”最后出现的位置。
4.lastIndexOf(String str,int fromIndex)
例5.8 查询字符串“01a3a56a89”中字母“a”的位置。
2.startsWith(String prefix,int toffset)
例5.10查询五言绝句《静夜思》的第二行是否以“举”字开头。
例5.12 创建一个字符串,将此字符串转换成一个字符数组,并分别输错字符数组中的每个元素。
例5.13创建字符串,输出相声眀中的《报菜名》,然后用contains()方法查看是否有“腊肉”和“汉堡”这两道菜。
例5.14输出字符串“为革命保护视力,眼保健操开始!”的最后半句话。
2.substring(int beginIndex,int endIndex)
1.repiace(CharString target,CharSequence repiacement)
例5.16字符串“明月几时有,把酒问青天”中的“月”替换成“日”。
2.replaceAll(String regex,String repiacement)
例5.17分别使用replace()方法和repiaceAll()方法,利用正则表达式将字符串中所有的数字替换成“?”。
3.repiaceFirst(String regex,String repiacement)
例5.18现有字符串“8I want to marry you,so I nedd you !”,去掉第一个数字,再把第一次出现的“you”替换成“her”。
2.split(String regex,int limit)
例5.21将字符串“192.168.0.1”按照“.”拆分两次,第一次全部拆分,第二次拆分两次。
例5.22将字符串“abcDEF”分别用大写、小写两种格式输出。
例5.23将字符串“abc DEF‘”分别用大写,小写两种格式输出
例5.24利用正表达式///s,将字符串所有的空白内容替换成空字符
例5.26创建String变量,分别用=和equals()方法判断两个字符串是否相等
2.equalsIgnoreCase(String anotherString)
例5.27使用equals()和 equalsIgnoreCase()方法判断两个字符串是否相等。
(1)format(String format,Object…args)
(2)format(Local 1,String format,Object…args)
例5.28实现当前时间信息以4位年份,月份全称,2位日期格式输出
例5.29实现当前时间信息以2位小时数,2位分钟数,2位秒钟形式输出
例5.33创建StringBuffer对象,使用appeng()追加字符序列
3.setCharAt(int index,char ch)
例5.34创建StringBuffer对象,将索引为3的字符修改成A
4.insert(int offset,String str)方法
例5.35创建StringBuffer对象,在索引为5 的位置插入字符串F
例5.36创建StringBuffer对象,将其字符序列反序输出
例5.37创建StringBuffer对象,删除从索引4开始至索引7之前的内容
例5.38 StringBuffer类中类似String类的方法。
例5.39 创建StringBuilder字符序列对象,对其做追加、插入、删除 和反序输出操作。
5.5.3 StringBuffer、StringBuilder、 String 之间的关系
1. StringBuffer、StringBuilder、String 互相转换
例5.40 创建StringBuffer对象、StringBuilder对象、 String 对象,并将三者的内容互相转换。
例5.41 在项目中创建Jerque,在方法中编写如下代码,验证字符串操作和字符串生成器操作的效率。
5.1 String类
5.1.1 声明字符串
字符串是常量,它们可以显示任何文字信息,字符串的值在创建之后不能更改。在Java 语言中,单引号中的内容表示字符。
Java 通过 java.lang.String 这个类来创建可以保存字符串的变量,所以字符串变量是一个对象。
5.1.2 创建字符串赋值方法
1、引用字符串常量
2、利用构造方法实例化
3、利用字符数组实例化
4、提取字符数组中的一部分创建字符串对象
例5.1 编写一段代码,声明多个字符串变量,用不同的赋值方法给这些字符串变量赋值并输出。
public class CreateString {
public static void main(String[] args) {
String a="时间就是金钱,我的朋友。";//直接引用字符串常量
System.out.println("a="+a);
String b=new String("我爱清汤小肥羊");//利用构造方法实例化
String c=new String(b);//使用已有字符串变量实例化
System.out.println("b="+b);
System.out.println("c="+c);
char[] charArray= {'t','i','m','e'};
String d=new String(charArray);//利用字符数组实例化
System.out.println("d="+d);
char[] charArray2= {'时','间','就','是','金','钱'};//提取字符数组部分内容,从下标为4开始,截取两个字符
String e=new String(charArray2,4,2);
System.out.println("e="+e);
}
}
5.2 连接字符串
对于已声明的字符串,可以对其进行相应的操作。连接字符串就是字符操作中较简单的一种。可以对多个字符串进行连接,也可使字符串与其他数据类型进行连接
5.21 连接字符串
使用“+”运算符可实现拼接多个字符串的功能,“+”运算符可以连接多个字符串并产生一个 String 对象。除了“+”运算符,“+=”同样可以实现字符串拼接。
例5.2使用“+”和“+=”拼接字符串
public class StringConca {
public static void main(String[] args) {
String a="abc";
String b="123";
String c=a+b+"!";//使用“+”拼接字符串
String d="拼接字符串";
d+=c;//使用“+=”拼接字符串
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("c="+c);
System.out.println("d="+d);
}
}
字符串是常量,是不可修改的。拼接两个字符串之后,原生的字符串不会发生变化,而是在内存中生成一个新的字符串。
5.22 连接其他数据类型
字符串也可同其他基本数据类型进行连接。如果将字符串同这些数据类型进行连接,会将这些数据直接转换成字符串。
例5.3 在项目中创建类Link,在主方法中创建数值型变量,实现将字符串与整型、浮点型变量相连的结果输出。
public class Link {
public static void main(String[] args) {
int booktime=4;//声明Int型变量booktime
float practice=2.5f;//声明float型变量practice
System.out.println("我每天花费"+booktime+"小时看书"+practice+"小时上机练习");
}//将字符串与整型,浮点型变量相连,并将结果输出
}
5.3 提取字符串信息
字符串作为对象,可以通过相应的方法获取字符串的有效信息,如获取某字符串的长度、某个索引位置的字符等。
5.3.1 获取字符串长度
length()方法返回采用UTF-16的编码表示字符的数量,也就是char的数量。
5.3.2 获取指定的字符
charAt(String index)方法可将指定索引处的字符返回。
例5.4 创建字符串对象,查看字符串中索引位置是4的字符。
public class ChatAt {
public static void main(String[] args) {
String str="床前明月光,疑是地上霜";//创建字符串对象str
char chr=str.charAt(4);//将字符串str中索引位置为4的字符赋给a
System.out.println("字符串中索引位置为4的字符是:"+chr);
}
}
5.3.3 获取子字符串索引位置
String 类提供了两种查找字符串的方法,即indexOf()与lastIndexOf()方法。indexOf()方法返回的是搜索的字符或字符串首次出现的位置,lastIndexOf()方法返回的是搜索的字符或字符串最后一次出现的位置。
1. indexOf(String str)
该方法用于返回参数字符串在指定字符串str中首次出现的索引位置。当调用字符串的indexOf()方法时,会从当前字符串的开始位置搜索 str 的位置;如果没有检索到字符串 str,该方法的返回值是-1。
例5.5 创建字符串对象str,判断str中是否含有子字符串“abc”。
public class StringIndex {
public static void main(String[] args) {
String str="12345abcde";//创建字符串对象
int charIndex = str.indexOf("abc");// 获取字符串str中“abc”首次出现的索引,赋值给 charIndex
if (charIndex !=-1) { //判断:index的值不等于-1
//如果index不等于-1,则执行此行代码,说明str中存在“abc”字符串
System.out.println("str中存在abc 字符串");
}else{//如果index等于-1,则执行此行代码,说明str中没有“abc”字符串
System.out.println("str中没有abc字符串");
}
}
}
2.indexOf(String str,int fromIndex)
从指定的索引 fromIndex 开始至字符串最后,返回指定子字符串在此字符串中第一次出现处的索引。如果没有检索到字符串 str,该方法的返回值同样是-1。语法如下
a.indexOf(str,fromIndex)
a:任意字符串对象
str:要搜索的子字符串
fromIndex:开始搜索的索引位置
例5.6查找字符串“Weare the world”中“r”第一、二、三次出现的索引位置
public class String2 {
public static void main(String[] args) {
String str="We are the world";// 创建字符串
int firstIndex= str.indexOf("r");//获取字符串中“r”第一次出现的索引登
// 获取字符串中“r”第二次出现的索引位置,从第一次出现的索引位置之后开始查找
int secondIndex = str.indexOf("r", firstIndex + 1);
//获取字符串中“r”第三次出现的索引位置,从第二次出现的索引位置之后开始查找
int thirdIndex = str.indexOf("r", secondIndex + 1);
//输出三次获取的索引位置
System.out.println("r第一次出现的索引位置是:"+firstIndex);
System.out.println("r第二次出现的索引位置是:"+ secondIndex);
System.out.println("r第三次出现的索引位置是:"+thirdIndex);
}
}
3.public int lastIndexOf(String str)
返回指定字符串在此字符串中最右边出现处的索引。
例5.7 查找字符串“Let it go!Let it go”中单词“go”最后出现的位置。
public class String3 {
public static void main(String[] args) {
String str="Let it go!Let it go!"; //创建子付串多
int gIndex =str.lastIndexOf("g"); //返回“g”最后一次出现的位置最后一次出现的位置
int goIndex =str.lastIndexOf("go"); //返回“g”最后一次出现的位置最后一次出现的位置
int oIndex =str.lastIndexOf("o");//返回“o”最后一次出现的位置
System.out.println("字符串\"Let it go!Let it go!"+"中"+"\n");
System.out.println("\"g\"最后一次出现的位置是:"+gIndex);
System.out.println("\"o\"最后一次出现的位置是:"+oIndex);
System.out.println("\"go\"最后一次出现的位置是:"+goIndex);
}
}
4.lastIndexOf(String str,int fromIndex)
返回指定字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
例5.8 查询字符串“01a3a56a89”中字母“a”的位置。
public class StringLast {
public static void main(String[] args) {
String str="01a3a56a89";
int lastIndex =str.lastIndexOf("a");//返回字母“a”最后一次出现的索引位置//返回字母“a”的索引位置otherIndex
//满足0<=fiveBeforeIndex<=5条件,在满足条件的结果集中,返回最大的数字97
int fiveBeforeIndex = str.lastIndexOf("a", 5);
//返回字母“a”的索引位置otherIndex
//满足0<=threeBeforeIndex<=3条件,在满足条件的结果集中,返回最大的数字
int threeBeforeIndex = str.lastIndexOf("a",3);
System.out.println("字符串\"01a3a56a89\"中:\n");
System.out.println("字母\"a\"最后一次出现的位置是:"+lastIndex);
System.out.println("从索引位置5开始往回搜索,字母\"a\"最后一次出现的位置:"+fiveBeforeIndex);
System.out.println("从索引位置3开始往回搜索,字母\"a\"最后一次出现的位置:"+threeBeforeIndex);
}
}
5.3.4 判断字符串首尾内容
startsWith()和endsWith()方法分别用于判断字符串是否以指定的内容开始或结束。这两个方法的返回值都是boolean类型。
1. startsWith(String perfix)
该方法用于判断字符串是否以指定的前缀开始。
例5.9 查看一个字符串是否以“我有一个梦想”开始
public class StringStart {
public static void main(String[] args) {
String myDream1="我有一个梦想,幽谷上升,高山下降;";//前半句
String myDream2="坎坷曲折之路成坦途,圣光披露,满照人间。";//后半句打印整句话
System.out.println(myDream1+myDream2+"\n\t\t——马丁·路德金《我有一个梦想》\n");
boolean firstBool = myDream1.startsWith("我有一个梦想");//判断前半句是否以“我有一个梦想”为前缀
// 判断后半句是否以“我有一个梦想”为前缀
boolean secondBool= myDream2.startsWith("我有一个梦想");
if (firstBool){//判断前半句的逻辑结果
System.out.println("前半句是以\"我有一个梦想\"开始的。");
}else if (secondBool){//判断后半句的逻辑结果
System.out.println("后半句是以\"我有一个梦想\"开始的。");
}else{//如果没有符合条件的字符串
System.out.println("没有以\"我有一个梦想\"开始的。");
}
}
}
2.startsWith(String prefix,int toffset)
该方法用于判断从指定索引的子字符串字符串是否以指定的前缀开始。
例5.10查询五言绝句《静夜思》的第二行是否以“举”字开头。
public class StringStartW2 {
public static void main(String[] args) {
String str="床前明月光,疑是地上霜。\n举头望明月,低头思故乡";
System.out.println(" 《静夜思》\n"+ str+"\n");//打印古诗
int enterIndex = str.indexOf("\n");//返回换行符所在的位置
//返回从换行符之后开始的子字符串前缀是否为“举”
//换行符在字符串中只占一个字符,所以enterIndex+ 1
boolean flag = str.startsWith("举", enterIndex + 1);
if (flag) {
System.out.println("第二行是以\"举\"开始的");//如果结果为真,则输出计
} else {//如果结果为假,则输出第二行开头第一个字符
System.out.println("第二行是以\""+ str.charAt(enterIndex+1)+"\"开始的");
}
}
}
3.endsWith(String suffix)
该方法判断字符串是否以指定的后缀结束。
例5.11查看一个字符串是否以句号结尾。
public class StringEndWith {
public static void main(String[] args) {
String str1="你说完了吗?";
String str2="我说完了。";
boolean flag1=str1.endsWith("。");//判断str1是否以“。”结尾
boolean flag2=str2.endsWith("。");//判断tx2是否以“。”结尾
System.out.println("字符串str1是以句号结尾的吗?"+flag1);//输出结果"
System.out.println("字符串str2是以句号结尾的吗?"+flag2);
}
}
5.3.5 获取字符串数组
toCharArray()方法可以将字符串转换为一个字符数组。
例5.12 创建一个字符串,将此字符串转换成一个字符数组,并分别输错字符数组中的每个元素。
public class StringToArray {
public static void main(String[] args) {
String str="这是一个字符串";//创建一个字符串
char[] ch = str.toCharArray();//将字符串转换成字符数组
for (int i = 0; i< ch.length; i++) {//遍历字符数组
System.out.println("数组第"+i+"个元素为:"+ch[i]);
}
}
}
5.3.6 判断子字符串是否存在
contains()方法可以判断字符串中是否包含指定的内容。
例5.13创建字符串,输出相声眀中的《报菜名》,然后用contains()方法查看是否有“腊肉”和“汉堡”这两道菜。
public class StringContains {
public static void main(String[] args) {
String str="今天的菜单有:蒸羊羔,蒸熊掌,蒸鹿尾。烧花鸭,烧维鸡,烧子鹅,卤煮咸鸭,酱鸡,腊肉,松花小肚。";// 创建字符串
System.out.println(str);//输出字符串
boolean request1 = str.contains("腊肉");
//判断字符串中是否有“腊肉”的字样
System.out.println("今天有腊肉吗?"+request1);
boolean request2=str .contains("汉堡");//判断学符串中是否有“汉堡”的字样
System.out.println("今天有汉堡吗?"+request2);
}
}
5.4 字符串的操作
5.4.1 截取字符串
1.substring(int beginIndex)
该方法返回一个新的字符串,它是此字符串的一个子字符串。该子字符串从指定索引处的字符开始,直到字符串末尾。
例5.14输出字符串“为革命保护视力,眼保健操开始!”的最后半句话。
public class StringSub {
public static void main(String[] args) {
String str="为革命保护视力,眼保健操开始";
String substr=str.substring(8);//从第8句截取字符串
System.out.println("字符串str的后半句是:"+substr);
}
}
2.substring(int beginIndex,int endIndex)
该方法返回一个新的字符串,它是此字符串的一个子字符串。该子字符串从指定的beginIndex处开始,直到索引endIndex-1处的字符串。
例5.15取字符串“闭门造车,出门合辙。”的前半句话。
public class StringSub2 {
public static void main(String[] args) {
String str="闭门造车,出门合辙。";//从0开始(从头开始)截取至4-1索引位置的子字符串
String substr=str.substring((int) 0.4);
System.out.println("字符串str的前半句是:"+substr);
}
}
5.4.2 字符串替换
1.repiace(CharString target,CharSequence repiacement)
该方法可以实现将指定的字符序列替换成新的字符序列,CharSequence是一个接口,代表一个可读的字符序列,String、StringBuffer、StringBuilder都实现了这个接口,所以可以直接将字符串当成参数。
例5.16字符串“明月几时有,把酒问青天”中的“月”替换成“日”。
public class StringReplace {
public static void main(String[] args) {
String str="明月几时有,把酒问青天";
String restr=str.replace("月","日");//将str中的“月”全部提换成“日”
System.out.println("字符串str替换之后的效果:"+restr);
}
}
2.replaceAll(String regex,String repiacement)
该方法可以实现将指定的字符串替换成新的字符串,支持正则表达式。
例5.17分别使用replace()方法和repiaceAll()方法,利用正则表达式将字符串中所有的数字替换成“?”。
public class StringPiaceZAll {
public static void main(String[] args) {
String str="0123456789abc\\d";//创建字符串,前十位是数字
String restr=str.replace("\\d","?");//使用replace()将符合“//d"表达式的字符串替换”?“
String restrAll=str.replaceAll("\\d","?");使用replace()将符合“//d"表达式的字符串替换”?“
System.out.println("字符串str:"+str);
System.out.println("使用replace()替换的结果"+restr);
System.out.println("使用replaceAll()替换的结果"+restrAll);
}
}
3.repiaceFirst(String regex,String repiacement)
该方法可以实现将第一个指定的字符串替换成新的字符串,支持正则表达式。
例5.18现有字符串“8I want to marry you,so I nedd you !”,去掉第一个数字,再把第一次出现的“you”替换成“her”。
public class StringReplaceFirst {
public static void main(String[] args) {
String str="8 I want to marry you,so I need you!";//创建字符串
String noNumber=str.replaceFirst("\\d","");//将开头的数字替换成两个双引号“”
String youToHer=noNumber.replaceFirst("you","her");//将第一次出现的“you”替换成“her”
System.out.println("替换之后的结果是是:"+youToHer);//输出结果
}
}
5.4.3 字符串分割
1.split(String regex)
该方法可根据给定的分隔符对字符串进行拆分,支持正则表达式,最后返回一个字符数组。
例5.19创建一个字符串。用“,”分割。
public class StringSplit {
public static void main(String[] args) {
String str="从前有座山,山里有座庙,庙里有个小松鼠";//创建字符串
String[] strArray=str.split(",");//让字符串按照“,”,进行分割
for(int i=0;i<strArray.length;i++) {//使用for循环,循环输出数字所有元素
System.out.println("数组第"+ i +"索引的元素是:"+strArray[i]);
}
}
}
例5.20同时使用不同的分隔符,分割同一字符串。
public class StringSpilt2 {
public static void main(String[] args) {
String str ="alb2,c,d e flgh";//创建字符串,包含多种类型字符
String[] a1= str.split(",");//使用“,”分割
String[] a2 = str.split("");//使用空格分割
String[] a3 = str.split("\\|");//使用“1”分割
String[] a4 = str.split("\\d");//使用正则表达式分割,本行用数字分割//同时用“,”、空格、“1”、数字分割,用符号“1”连接所有分隔符
String[] a5 = str.split(",1 \\/\\d");
System.out.println("str的原值:["+ str+"]");//显示str的原值//使用for-each 循环展示“,”分割的结果
System.out.print("使用\",\"分割:");
for (String b : a1) {
System.out.print("["+b +"J");}
System.out.println(); // 换行
// 使用 for-each 循环展示空格分割的结果
System.out.print("使用空格分割:");
for (String b :a2) {
System.out.print("["+b+"]");}
System.out.println();
// 使用 for-each 循环 展示“l”分割的结果
System.out.print("使用\"|\"分割:");
for(String b :a3){
System.out.print("["+b+"]");}
System.out.println();
//使用for-each 循环展示数字分割的结果
System.out.print("使用数字分割:");
for(String b :a4){
System.out.print("["+b+"]");}
System.out.println();
// 使用 for-each 循环展示所有分隔符同时分割的结果
System.out.print("同时使用所有分隔符:");
for (String b:a5){
System.out.print("["+ b +"]");}
System.out.println();}}
2.split(String regex,int limit)
该方法可根据给定的分隔符对字符串进行拆分,并限定拆分的次数,支持正则表达式。
例5.21将字符串“192.168.0.1”按照“.”拆分两次,第一次全部拆分,第二次拆分两次。
public class StringSplit3 {
public static void main(String[] args) {
String str="190.168.01";
String[] firstArray= str.split("\\.");//按照“.”进行分割
String[] secondArray= str.split("\\.",2);// 按照“.”进行两次分割
System.out.println("str的原值为:["+ str+"]");//输出str原值
//输出全部分割的结果
System.out.print("全部分割的结果:");
for (String a :firstArray){
System.out.print("["+ a +"]");}
System.out.println();//换行
// 输出分割两次的结果
System.out.print("分割两次的结果:");
for (String a :secondArray){
System.out.print("["+ a+"]");}
System.out.println();
}
}
5.4.4 大小写转换
1.toLowerCase()
该方法将String转换为大小写。如果字符串中没有应被转换的字符,则将原字符串返回;否责将返回一个新的字符串,将原字符串中每个可进行小写转换的字符都转换成等价的写字符。字符串与原字符长度相同。
2.toUpperCase()
该方法将String转换为大写。如果字符串中没有应被转换的字符,则将原字符串返回;否则返回一个新的字符串,将原字符串中每个可进行大写转换的字符都转换等价的字符大写。新字符串等于旧字符长度相同。
例5.22将字符串“abcDEF”分别用大写、小写两种格式输出。
public class StringTransform {
public static void main(String[] args) {
String str="abc DEF";//创建字符串
System.out.println(str.toLowerCase());//按照小写格式输出
System.out.println(str.toUpperCase());//按照大写格式输出
}
}
5.4.5 去除空白内容
trim()方法可以通过返回字符串的副本,忽略首尾空白。
例5.23将字符串“abc DEF‘”分别用大写,小写两种格式输出
public class StringTrim {
public static void main(String[] args) {
String str=" abc ";
String shortStr=str.trim();
System.out.println("str的原值是:+["+str+"]");
System.out.println("去掉首尾空白的值:+["+shortStr+"]");
}
}
例5.24利用正表达式///s,将字符串所有的空白内容替换成空字符
public class StringRemove {
public static void main(String[] args) {
String str=" a b cd e f g ";
String shortStr=str.replaceAll("\\s","");
System.out.println("str的原值是:+["+str+"]");
System.out.println("去掉首尾空白的值:+["+shortStr+"]");
}
}
5.4.6 比较字符串是否相等
对字符串对象进行比较不能简单地使用比较运算符“==”因为比较运算符比较的是两个字符串的内存地址是否相同。因为即使两个字符串的文本值相同,两个对象的内存地址也可能不同,所以使用比较运算符会返回false.
例5.25使用比较运算符比较两个字符串
public class StringCompare {
public static void main(String[] args) {
String tom,jerry;//直接引入字符串常量
tom="I am a student";
jerry="I am a student";
System.out.println("直接引入字符串常量的比较结果:"+(tom==jerry));
tom=new String("I am a student");
jerry=new String("I am a student");
System.out.println("使用new创建对象的比较结果:"+(tom==jerry));
}
}
1.equals(String str)
将此字符串与指定的对象比较。当且仅当该参数不为null,并且是与此对象表示相同字符串序列的String对象时,结果才为 true。
例5.26创建String变量,分别用=和equals()方法判断两个字符串是否相等
public class StringEquals {
public static void main(String[] args) {
String str1="Hello";
String str2=new String("Hello");
String str3=new String("你好");
String str4=str2;
System.out.println("str1=str2的结果:"+(str1=str2));
System.out.println("str1=str3的结果:"+(str1=str3));
System.out.println("str1=str4的结果:"+(str1=str4));
System.out.println("str2=str4的结果:"+(str2=str4));
System.out.println("str1.equals(str2)的结果:"+str1.equals(str2));
System.out.println("str1.equals(str3)的结果:"+str1.equals(str3));
System.out.println("str1.equals(str4)的结果:"+str1.equals(str4));
}
}
2.equalsIgnoreCase(String anotherString)
将此字符串对象与指定的对象比较,不考虑大小写。如果两个字符串的长度相同,并且其中相应的字符都相等(忽略大小写),则认为这两个字符串是相等的。
例5.27使用equals()和 equalsIgnoreCase()方法判断两个字符串是否相等。
public class StringEqalsIu {
public static void main(String[] args) {
String str1="abc";
String str2="ABC";
System.out.println("区分大小写的结果:"+str1.equals(str2));
System.out.println("不区分大小写的结果:"+str1.equalsIgnoreCase(str2));
}
}
5.4.7格式化字符串
String 类的静态format()方法用于创建格式化的字符串。 format()方法有两种重载形式。
(1)format(String format,Object…args)
该方法使用指定的格式字符串和参数返回一个格式字符串,格式化后的新字符串使用本地默认的语言环境。
(2)format(Local 1,String format,Object…args)
1.日期和时间字符串格式化
在应用程序设计中,经常需要显示时间和日期。如果想输出满意的日期和时间格式,一般需要编写大量的代码经过各种算法才能实现。format()方法通过给定的特殊转换符作为参数来实现对日期和时间的格式化。
(1)日期格式化
例5.28实现当前时间信息以4位年份,月份全称,2位日期格式输出
import java.util.Date;
public class Eval {
public static void main(String[] args) {
Date date = new Date(); //创建 Date 对象 date
String year = String.format("%tY", date); //将date进行格式化
String month = String. format("%tB", date);
String day =String.format("%td", date) ;
//输出的信息
System.out.println("今年是:"+ year +"年");
System.out.println("现在是:"+ month);
System.out.println("今天是:"+ day +"号");
}
}
(2)时间格式化
使用format()方法不仅可以完成日期的格式化,也可以实现时间的格式化。时间格式化转换要比日期转换符更多、更精准,它可以将时间格式化为时、分、秒、毫秒。
例5.29实现当前时间信息以2位小时数,2位分钟数,2位秒钟形式输出
import java.util.Date;
public class GetDate {
public static void main(String[] args) {
Date date = new Date(); //创建 Date 对象 date
String hour = String.format("%tH", date); //将date进行格式化
String minute = String. format("%tM", date);
String second =String.format("%tS", date) ;
//输出的信息
System.out.println("现在是:"+ hour+"时"+ minute +"分"+ second +"秒");
}
}
例5.30输出当前日期
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) {
Date date = new Date(); //创建 Date 对象 date
String time = String.format("%tc", date); //将date进行格式化
String form = String. format("%tF", date);
String second =String.format("%tS", date) ;
//输出的信息
System.out.println("全部时间信息是:"+time);
System.out.println("年-月-日格式:"+form);
}
}
例5.31实现不同类型的格式转换
public class StringFormat {
public static void main(String[] args) {
String str1 = String.format("%c",'×');//输出字符System.out.print1n(”字母x大写:"+str1);
String str2 = String.format("%d",1251 + 3950);//输出数字
System.out.println("1251+3950的结果是:"+ str2);
String str3 = String.format("%.2f", Math.PI);// 输出小数点后
System.out.println("π取两位小数点:"+ str3);
String str4 = String.format("%b",2<3);// 输出布尔值
System.out.println("2<3的结果是:"+ str4);
String str5=String.format("%h",3510);// 输出哈希散列码,等同Integer.toHexString(3510);
System.out.println("3510的hashCode值:"+ str5);
String str6 = String.format("%o",33);// 输出8进制
System.out.println("33的8进制结果是:"+ str6);
String str7 = String.format("%x",33);//输出16进制
System.out.println("33的16进制结果是:"+ str7);
String str8 = String.format("%e",120000.1);// 输出科学计数法
System.out.println("120000.1用科学计数法表示:"+ str8);
String str9 = String.format("%a",40.0);// 输出带有效位数和指数的16进制浮点值
System.out.println("40.0的16进制浮点值:"+ str9);
//输出百分号和数字
System.out.println(String.format("天才是由%d%%的灵感,d的汗水。",1,99));
}
}
例5.32使用标识控制字符串的输出格式
public class StringFormat2 {
public static void main(String[] args) {
String str1= String.format("%5d", 123);//让字符串输出的最大长度为5.不是长度在前端补空格
System.out.println("输出长度为5的字符串|"+ str1+"|");//让字符串左对齐
String str2 = String.format("%-5d",123);//让字符串左对齐
System.out.println("左对齐|"+ str2+"|");
String str3= String.format("%#o",33);//在8进制前加一个。
System.out.println("33的8进制结果是:"+str3);
String str4=String.format("%#x",33);//在16进制前加一个
System.out.println("33的16进制结果是:"+str4);
String str5=String. format("%+d",1);// 显示数字正负号
System.out.println("我是正数:"+str5);
String str6 = String.format("%+d",-1);//显示数字正负号
System.out.println("我是负数:"+ str6);
String str7= String.format("% d",1);//在正数前补一个空格
System.out.println("我是正数,前面有空格"+str7);
String str8= String.format("% d",-1);//在负数前补一个负号
System.out.println("我是负数,前面有负号"+str8);
String str9= String.format("%05d",12);//读字符排锦出的最大长度为5.不是。度在前端补0
System.out.println("前面不够的数用0填充:"+ str9);
String str10 = String.format("%,d",123456789);//用逗号分隔数字
System.out.println("用逗号分隔:"+str10);
String str11 = String.format("%(d",13);//正数无影响
System.out.println("我是正数,我没有括号:"+str11);
String str12 = String.format("%(d",-13);//让负数用括号括起来
System.out.println("我是负数,我有括号的:"+str12);
}
}
5.5可变字符串
StringBuffer是线程安全的可变字符序列,一个类似于String的字符串缓冲区。前面内容介绍过String 创建的字符串对象是不可修改的,这一节介绍的 StringBuffer 类创造的字符串序列是可修改的,且实体容量会随着存放的字符串增加而自动增加。StringBuilder 与 StringBuffer 有完全相同的APl,只是为了提高效率而放弃了线程安全控制。
5.5.1StringBuffer类的常用方法
1.创建StringBuffer类
创建一个新的StringBuffer对象必须用new方法,而不能像String对象那样直接引用字符串常量。
2.append()方法
将参数转换此字符串,将所得字符串中的字符追加到此序列中。
例5.33创建StringBuffer对象,使用appeng()追加字符序列
public class StringBuff {
public static void main(String[] args) {
StringBuffer sbf = new StringBuffer("门前大桥下,");//创建StringBuffer对象
sbf.append("游过一群鸭,");// 追加字符串常量
StringBuffer tmp = new StringBuffer("快来快来数一数,");// 追加StringBuffer 对象
sbf.append(tmp);
int x=24678;
sbf.append(x);// 追加整型变量
System.out.println(sbf.toString());//输出
}
}
3.setCharAt(int index,char ch)
将给定索引的字符修改为ch。
例5.34创建StringBuffer对象,将索引为3的字符修改成A
public class StringBufferSetChar {
public static void main(String[] args) {
StringBuffer sbf = new StringBuffer("0123456");
System.out.println("sbf的原值是:"+sbf); //将索引为3的字符改成‘x”
sbf.setCharAt(3, 'A');
System.out.println("修改后的值是:"+sbf);
}
}
4.insert(int offset,String str)方法
将字符串插入此字符序列中
例5.35创建StringBuffer对象,在索引为5 的位置插入字符串F
public class StringRemove {
public static void main(String[] args) {
String str=" a b cd e f g ";
String shortStr=str.replaceAll("\\s","");
System.out.println("str的原值是:+["+str+"]");
System.out.println("去掉首尾空白的值:+["+shortStr+"]");
}
}
5.reverse()方法
该方法可以将字符反序输出。
例5.36创建StringBuffer对象,将其字符序列反序输出
public class StringBufferReverse {
public static void main(String[] args) {
StringBuffer sbf = new StringBuffer("同一个世界,同一个梦想");
System.out.println("sbf的原值为:"+sbf);
sbf= sbf.reverse();// 将字符序列sbf反转
System.out.println("修改之后的值为:"+sbf);
}
}
6.delete(int start,int end)方法
移除此序列的子字符串中的字符。该子字符串是从指定的索引 start处开始,一直到索引end-1处,如果
end-1 超出最大索引范围,则一直到序列尾部。如果 start 等于end,则不发生任何更改。
例5.37创建StringBuffer对象,删除从索引4开始至索引7之前的内容
public class StringBufferDelete {
public static void main(String[] args) {
StringBuffer sbf = new StringBuffer("天行健,君子以自强不息");
System.out.println("sbf的原值为:"+sbf);
sbf= sbf.delete(4,7);// 删除从索引4开始至索引7之前的内容
System.out.println("删除之后的值为:"+sbf);
}
}
例5.38 StringBuffer类中类似String类的方法。
public class StringBufferTest38 {//创建主类
public static void main(String[] args) {//主方法
StringBuffer sbf =new StringBuffer("ABCDEFG");// 创建字符串序列
int lenght =sbf.length();//获取字符串序列的长度
char chr=sbf.charAt(5);//获取索引为5的字符
int index=sbf.indexOf("DEF");// 获取 DEF 字符串所在的索引位置
String substr=sbf.substring(0,2);//截取从索引0开始至索引2之间的字符串
StringBuffer tmp =sbf.replace(2,5,"1234");// 将从索引2开始至索引之间的字符序列替换成“1234”
System.out.println("sbf的原值为:"+sbf); //输出结果
System.out.println("sbf的长度为:"+lenght);// 输出结果
System.out.println("索引为5的字符为:"+chr);//输出结果
System.out.println("DEF字符串的索引位置为:" + index);//输出结果
System.out.println("索引0开始至索引2之间的字符串:" + substr);//输出结果
System.out.println("替换后的字符串为:" + tmp);//输出结果
}
}
5.5.2StringBuilder类的使用方法
StringBuilder类与StringBuffer类具有兼容的API,所以两者的使用方法也相同。
例5.39 创建StringBuilder字符序列对象,对其做追加、插入、删除 和反序输出操作。
public class StringBuilderTest39 {//创建主类
public static void main(String[] args) {//主方法
StringBuilder sbd =new StringBuilder();//创建StringBuffer对象
System.out.println("sbd的原值为空");//输出结果
sbd.append("我是StringBuilder类");//将参数转换为字符串
System.out.println("sbd追加字符串:"+ sbd);// 输出结果
int length = sbd.length();//赋值
System.out.println("sbd的长度为:"+length);// 输出结果
sbd=sbd.insert(length-1,"123456"); //在索引为length-1的位置插入“123456”,将返回值赋给sbd
System.out.println("插入字符串:"+ sbd);//输出结果
sbd=sbd.delete(sbd.length()-1, sbd.length());// 删除索引sbd.length()-1开始至索引sbd.length()之前的内容
System.out.println("删除最后一个字:"+sbd); //输出结果
sbd = sbd.reverse();//将字符序列 sbd 反转
System.out.println("反序输出:"+ sbd);//输出结果
}
}
5.5.3 StringBuffer、StringBuilder、 String 之间的关系
1. StringBuffer、StringBuilder、String 互相转换
StringBuffer类和 StringBuilder类都有toString()方法,可以返回字符序列的字符串表示形式。这两个类在初始化的时候,可以通过字符串作为参数,指定初始化的字符序列内容
例5.40 创建StringBuffer对象、StringBuilder对象、 String 对象,并将三者的内容互相转换。
public class StringInterchange40 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
String str = "String";
StringBuffer sbf = new StringBuffer(str); //String转换StringBuffer
StringBuilder sbd = new StringBuilder(str); //String转换StringBuilder
str = sbf.toString(); //StringBuffer转换String
str = sbd.toString(); //StringBuilder转换String
StringBuilder bufferToBuilder = new StringBuilder(sbf.toString()); //StringBuffer转换StringBuilder
StringBuffer BuilderToBuffer = new StringBuffer(sbd.toString()); //StringBuilder转换StringBuffer
}
}
2. StringBuffer、StringBuilder、String的不同之处
String只能赋值一次,每一次内容发生改变都生成了一个新的对象,然后原有的对象引用新的对象,所以说 String 本身是不可改变。每一次改变 String 的字符串内容,都会在内存创建新的对象,而每一次生成新对象都会对系统性能产生影响。
而StringBuffer和StringBuilder不同,每次操作都是对自身对象做操作,而不是生成新的对像,其所占空间会随着字符内容增加而扩充,做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。
StringBuffer 和 StringBuilder 也存在不同之处。StringBuffer的方法都使用"synchronized”关键字进行修饰,这样保证了同时最多只有一个线程可以运行这些方法,也就是保证了线程安全。 StringBuilder则不具备这样的特点。反过来说,正因为StringBuilder 没有线程安全机制,运行起来就不用考虑给线程加锁,所以运行效率会比 StringBuffer 要高。
例5.41 在项目中创建Jerque,在方法中编写如下代码,验证字符串操作和字符串生成器操作的效率。
public class Jerque{ //新建类
public static void main(String[] args) { //主方法
String str =""; //创建空字符串
long starTime = System.currentTimeMillis(); //定义对字符串执行操作的起始
for (int i = 0; i < 10000; i++) { //利用for 循环执行 10000次
str=str+i; //循环追加字符串
}
long endTime = System.currentTimeMillis(); //定义对字符串操作后的时间
long time = endTime - starTime; //计算对字符串执行操作的时间
System.out.println("String循环1万次消耗时间:"+ time);//将执行的时间输出
StringBuilder builder = new StringBuilder("");//创建字符串生成器
starTime = System.currentTimeMillis(); //定义操作执行前的时间
for (int j =0; j<10000; j++){ //利用for循环进行业
builder.append(j); //循环追加字符
}
endTime =System.currentTimeMillis();//定义操作后的时间
time = endTime- starTime;//追加操作执行的时间
System.out.println("StringBuilder循环1万次消耗时间:"+ time);//将执行的时间输出
StringBuilder builder2 = new StringBuilder("");//创建字符串生成器
starTime = System.currentTimeMillis();//定义操作执行前的时间
for (int j = 0; j < 50000;j++){//利用for循环进行操作
builder2.append(j);//循环追加字符
}
endTime = System.currentTimeMillis();//定义操作后的时间
time = endTime - starTime;//定义时间的值
System.out.println("StringBuilder循环5万次消耗时间:" + time);//输出结果
}
}
本章小结
String的特点:
字符串是由多个字符组成的一串数据
字符串是常量,一旦被创建就不能改变,这是因为字符串的值是存放在方法区的常量池里面,但是引用可以改变。
在Object类里边equals方法和“==”是相同的,都是用来判断两个对象的地址是否相等,即两个对象是否是同一个对象。
总结来说:
(1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
(2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。
效率从高到低排列:StringBuilder > StringBuffer > String
String 类型和 StringBuffer 的主要性能区别:String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String
如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况