学习目标:掌握动态生成字符串的方法和字符串的格式化操作。
字符串生成器
在Java语言中,String对象被创建成功后,它的长度和内容都不能再改变。对String对象使用赋值和连接运算符改变内容时,都会在内存中产生一个新的String对象。如果对String对象多次进行连接或赋值操作,会导致程序占用较多内存,系统开销增大,这种情况是要尽量避免的。
Java API库提供了StringBuilder类,来解决字符串多次修改的问题。StringBuilder类允许程序频繁修改字符串内容,而不会在内存中创建新的字符串对象。StringBuilder类修改字符串内容的主要操作方法如下:
(1)append()方法
append()方法用于添加内容到字符串生成器,它是重载方法,它可以添加不同数据类型的内容到字符串生成器,如String、CharSequence、char、double、int、float等类型。
调用语法如下:
builder. append(content)
其中,builder是已创建的StringBuilder对象。content是指要添加的内容,它可以是任何类型的数据或类对象。
(2)in sert()方法
in sert()方法用于向字符串生成器的指定位置插入内容,它也是重载方法,它可以插入不同数据类型的内容到字符串生成器。
调用语法如下:
builder. in sert(int offset, content)
其中,builder是已创建的StringBuilder对象。offset是字符串生成器的索引位置,在该索引位置插入content。content可以是任何类型的数据或类对象。
(3)de lete(int statr int end)方法
del ete()方法用于从字符串生成器中删除指定索引范围内的子串。该子串从指定的start开始,一直到索引end-1处的字符,如果end索引不存在,则到字符串生成器的尾部。如果start和end相等,该方法不做任何操作。
案例8:创建StringBuilder对象和String对象,在循环结构中使用StringBuilder对象的append()方法添加字符串,使用“+=”运算符为String对象添加字符串,验证String类和StringBuilder类添加字符串的效率。
在Punit4项目unit包下创建Case8类。代码如下:
package unit;
public class Case8 {
public static void main(String[] args) {
// 创建String对象
String szTemp = "";
// 创建StringBuilder对象
StringBuilder builder = new StringBuilder();
//获取操作前时间(毫秒数)
long startTime = System.currentTimeMillis();
// 循环10000次,循环追加字符串
for( int i = 0 ; i < 100000; i++ )
{
szTemp += i;
}
//获取操作后时间(毫秒数)
long endTime = System.currentTimeMillis();
// 计算szTemp追加字符串操作时间
long nTime = endTime - startTime;
System.out.println("String消耗时间:"+ nTime);
//获取操作前时间(毫秒数)
startTime = System.currentTimeMillis();
// 循环10000次,循环追加字符串
for( int i = 0 ; i < 100000; i++ )
{
builder.append(i);
}
//获取操作后时间(毫秒数)
endTime = System.currentTimeMillis();
// 计算builder追加字符串操作时间
nTime = endTime - startTime;
System.out.println("StringBuilder消耗时间:"+ nTime);
}
}
程序分别创建了String对象和StringBuilder对象。程序设置两轮循环,循环次数为100000次,在每轮循环开始前,调用System.currentTimeMillis()方法获取循环前时间,循环结束后获取循环后时间,用于计算循环耗费的时间并输出。在第一轮循环体内,szTemp对象使用“+=”运算符追加循环变量i的值;在在第二轮循环体内builder对象调用append()方法追加循环变量i的值。
程序执行结果如下图所示:

从执行结果可以看出,StringBuilder类和String类操作字符串的效率差别很大,当在程序中频繁使用附加字符串时,建议使用StringBuilder类,当附加字符串操作结束后,可以使用StringBuilder类的toString()方法返回一个String对象。
字符串的格式化
在编写程序时,有时需要对字符串进行格式化输出。String类的format()方法可以对字符串进行格式化。
调用format()方法的语法如下:
String.format(
String format,
Object... args
)
format()方法是String类的静态方法,调用该方法可以直接使用String类名来调用,不需要创建String对象后再调用。
参数format是格式化串,是符合格式字符串语法描述的字符串。args是格式化串中格式说明符引用的参数,参数的数量是可变的,可以为零。
format格式化串和args可变参数的应用请参考第2单元的《格式化输出》一课内容。
案例9:format方法的应用。
在Punit4项目unit包下创建Case9类。代码如下:
package unit;
public class Case9 {
public static void main(String[] args) {
/**
* 创建字符串对象
*/
String szTemp = "格式化输出演示";
/**
* 声明双精度浮点变量并赋值,
*/
double dTemp = 129.6789603;
/**
* 声明字符型变量并赋值,
*/
char chTemp = 'a';
/**
* 创建字符串对象
*/
String str = "";
// 用format方法格式化szTemp,字符串前后分别填充2个*字符
str = String.format("**%s**\n", szTemp) ;
System.out.println(str);
// 用format方法格式化dTemp,位数宽度为9,保留2为有效小数,空位用0填充
str = String.format("%s:%09.2f\n", "输出浮点型变量", dTemp);
System.out.println(str);
// 用format方法格式化chTemp,分别输出字符、十进制、十六进制
str = String.format("%s:%c:\n十进制:%d:\n十六进制:%x\n", "输出字符型变量", chTemp, (int) chTemp, (int) chTemp);
System.out.println(str);
}
}
在“String.format("**%s**\n",szTemp);”语句中,“”**%s**\n"”是格式字符串,%s表示输出字符串,字符串的内容来自szTemp,%s前面和后面的**是要输出的字符串内容,格式字符串里面可以添加任何想要输出的内容。\n是换行符,下次输出时将会另起一行。
在“String.format ("%s:%09.2f\n","输出浮点型变量",dTemp); ”语句中,第一个%s的内容来自于格式字符串后面的第一个字符串参数“输出浮点型变量”,%09.2f表示输出9位数浮点数,保留2位有效小数,位数不足的,前面用0填充,浮点数值内容来自于dTemp。
该语句也可以改写为下面的语句,效果是等同的:
System.out.printf("输出浮点型变量:%09.2f\n",dTemp);
在格式化字符型变量语句中,分别应用%c、 %d和%x将字符型变量按照字符、十进制数值和十六进制数值格式化,其中“(int)”是将字符类型强制转换为int类型操作符,其意义是将字符强制转换为数值输出。
日期和时间的格式化
在编写程序时,经常需要对日期进行格式化输出。使用String类的format方法可以实现对日期和时间的格式化输出。
日期的格式化输出
Java提供了日期格式化转换符用于支持日期的格式化输出,格式化转换符如下表所示:
案例10:使用API库的Date类获取当前日期和时间信息,并用format()方法将日期格式化为“XXXX年XX月XX日”的格式。
在Punit4项目unit包下创建Case10类。代码如下:
package unit;
import java.util.Date;
public class Case10 {
public static void main(String[] args) {
/**
* 创建一个Date对象,获取当前日期和时间
* Date类在Java.util包
* 使用import语句导入Java.util.Date
*
*/
Date date = new Date();
// 使用String类format()方法格式化日期
String szDate = String.format("当前日期为:%tY年%tm月%td日", date,date,date);
System.out.println(szDate);
}
}
Date类在Java. util包内,需要使用import语句导入Java. util.Date类。使用new运算符创建Date对象后,Date对象会自动获取当前日期和时间,创建的Date对象为变量date。
使用String类format()方法格式化日期,任务要求日期格式化为“XXXX年XX月XX日”,在format()方法的格式化串中使用了%tY、%tm、%td格式化符,%tY获取Date对象的4位年份(如2019),%tm获取Date对象的2位月份(如06),%td获取Date对象的2位天数(如12),format()方法的args参数使用date变量。
时间的格式化输出
String类的format()方法也可以对时间进行格式化,Java提供了时间格式化转换符用于支持时间的格式化输出,时间格式化转换符如下表所示:
案例11:使用API库的Date类获取当前日期和时间信息,并用format()方法将时间格式化为“XX时XX分XX秒”的格式。
在Punit4项目unit包下创建Case11类。代码如下:
package unit;
import java.util.Date;
public class Case11 {
public static void main(String[] args) {
/**
* 创建一个Date对象,获取当前日期和时间
* Date类在Java.util包
* 使用import语句导入Java.util.Date
*
*/
Date date = new Date();
// 使用String类format()方法格式化时间
String szDate = String.format("当前时间为:%tH时%tM分%tS秒", date,date,date);
System.out.println(szDate);
}
}
使用String类format()方法格式化时间,任务要求时间格式化为“XX时XX分XX秒”,在format()方法的格式化串中使用了%tH、%tM、%tS格式化符,%tH获取Date对象的2位小时数(如16),%tM获取Date对象的2位分钟数(如20),%tS获取Date对象的2位秒数(如35),format()方法的args参数使用date变量。
日期和时间组合格式化符
为便于程序员方便格式化日期和时间,Java提供了日期和时间的组合格式化符。组合格式符如下表所示:
案例12:使用API库的Date类获取当前日期和时间信息,并用format()方法将时间格式化为“XXXX-XX-XX:XX:XX:XX”的格式。
在Punit4项目unit包下创建Case12类。代码如下:
package unit;
import java.util.Date;
public class Case12 {
public static void main(String[] args) {
/**
* 创建一个Date对象,获取当前日期和时间
* Date类在Java.util包
* 使用import语句导入Java.util.Date
*
*/
Date date = new Date();
// 使用String类format()方法格式化日期
String szDate = String.format("当前时间为:%tF:%tT", date,date);
System.out.println(szDate);
}
}
使用String类format()方法格式化时间,任务要求时间格式化为“XXXX-XX-XX:XX:XX:XX”,在format()方法的格式化串中,使用了日期和时间组合格式化符%tF和%tT,%tF格式化日期为2018-9-18,%tT格式化时间为15:23:50,format()方法的args参数使用date变量。