textformat java_java.text.MessageFormat 专题

java.text.MessageFormat类

MessageFormat提供一种语言无关的方式来组装消息,它允许你在运行时刻用指定的参数来替换掉消息字符串中的一部分。你可以为MessageFormat定义一个模式,在其中你可以用占位符来表示变化的部分:

importjava.text.MessageFormat;importjava.util.Date;public classMessageFormatTest {public static voidmain(String[] args) {

Object[] arguments={7,newDate(System.currentTimeMillis()),"a disturbance in the Force"};

String result=MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",

arguments);

System.out.println(result);//output://At 14:08:27 on 2017-7-7, there was a disturbance in the Force on planet 7.

}

}

占位符的格式为{ ArgumentIndex, FormatType, FormatStyle},详细说明可以参考MessageFormat的API说明文档。这里我们定义了两个占位符,其中的数字对应于传入的参数数组中的索引,{0}占位符被第一个参数替换,{1}占位符被第二个参数替换,依此类推。

@TestvoidmessageFormatTest() {

String msg= MessageFormat.format("{0}1_{1} 2_\"{1}\"", "W0", "W1");

assertThat(msg).isEqualTo("W01_W1 2_\"W1\"");

msg= MessageFormat.format("{0}1_{1} 2_'{1}'", "W0", "W1");

assertThat(msg).isEqualTo("W01_W1 2_{1}");

}

最多可以设置10个占位符,而且每个占位符可以重复出现多次,而且格式可以不同,比如{1,date}和{1,time},{1,number,#.##}。而通过将这些模式定义放到不同的资源文件中,就能够根据不同的locale设置,得到不同的模式定义,并用参数动态替换占位符。

步骤:

1、找出可变的部分,并据此定义模式,将模式放入不同的资源文件中。

2、创建MessageFormat对象,并设置其locale属性。

MessageFormat formatter = new MessageFormat("");

formatter.setLocale(currentLocale);

3、从资源包中得到模式定义,以及设置参数。

messages = ResourceBundle.getBundle(

"i18n.resource.MessagesBundle",currentLocale);

Object[] arguments= {new Long(3), "MyDisk"};;

4、利用模式定义和参数进行格式化。

String result = MessageFormat.format(messages.getString(key), arguments);

http://blog.csdn.net/turkeyzhou/article/details/4487917

注意:

参数为Number类型或Date类型时,会被格式化。数字会转换成科学计数法,譬如 123456,会format成 123,456

java.text.MessageFormat#subformat

/*** Internal routine used by format. If characterIterators is

* non-null, AttributedCharacterIterator will be created from the

* subformats as necessary. If characterIterators is null

* and fp is non-null and identifies

* Field.MESSAGE_ARGUMENT, the location of

* the first replaced argument will be set in it.

*

*@exceptionIllegalArgumentException if an argument in the

* arguments array is not of the type

* expected by the format element(s) that use it.*/

privateStringBuffer subformat(Object[] arguments, StringBuffer result,

FieldPosition fp, ListcharacterIterators) {//note: this implementation assumes a fast substring & index.//if this is not true, would be better to append chars one by one.

int lastOffset = 0;int last =result.length();for (int i = 0; i <= maxOffset; ++i) {

result.append(pattern.substring(lastOffset, offsets[i]));

lastOffset=offsets[i];int argumentNumber =argumentNumbers[i];if (arguments == null || argumentNumber >=arguments.length) {

result.append('{').append(argumentNumber).append('}');continue;

}//int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);

if (false) { //if (argRecursion == 3){//prevent loop!!!

result.append('\uFFFD');

}else{

Object obj=arguments[argumentNumber];

String arg= null;

Format subFormatter= null;if (obj == null) {

arg= "null";

}else if (formats[i] != null) {

subFormatter=formats[i];if (subFormatter instanceofChoiceFormat) {

arg=formats[i].format(obj);if (arg.indexOf('{') >= 0) {

subFormatter= newMessageFormat(arg, locale);

obj=arguments;

arg= null;

}

}

}else if (obj instanceofNumber) {//format number if can

subFormatter =NumberFormat.getInstance(locale);

}else if (obj instanceofDate) {//format a Date if can

subFormatter =DateFormat.getDateTimeInstance(

DateFormat.SHORT, DateFormat.SHORT, locale);//fix

} else if (obj instanceofString) {

arg=(String) obj;

}else{

arg=obj.toString();if (arg == null) arg = "null";

}//At this point we are in two states, either subFormatter//is non-null indicating we should format obj using it,//or arg is non-null and we should use it as the value.

if (characterIterators != null) {//If characterIterators is non-null, it indicates we need//to get the CharacterIterator from the child formatter.

if (last !=result.length()) {

characterIterators.add(

createAttributedCharacterIterator(result.substring

(last)));

last=result.length();

}if (subFormatter != null) {

AttributedCharacterIterator subIterator=subFormatter.formatToCharacterIterator(obj);

append(result, subIterator);if (last !=result.length()) {

characterIterators.add(

createAttributedCharacterIterator(

subIterator, Field.ARGUMENT,

Integer.valueOf(argumentNumber)));

last=result.length();

}

arg= null;

}if (arg != null && arg.length() > 0) {

result.append(arg);

characterIterators.add(

createAttributedCharacterIterator(

arg, Field.ARGUMENT,

Integer.valueOf(argumentNumber)));

last=result.length();

}

}else{if (subFormatter != null) {

arg=subFormatter.format(obj);

}

last=result.length();

result.append(arg);if (i == 0 && fp != null &&Field.ARGUMENT.equals(

fp.getFieldAttribute())) {

fp.setBeginIndex(last);

fp.setEndIndex(result.length());

}

last=result.length();

}

}

}

result.append(pattern.substring(lastOffset, pattern.length()));if (characterIterators != null && last !=result.length()) {

characterIterators.add(createAttributedCharacterIterator(

result.substring(last)));

}returnresult;

}

Java里从来少不了字符串拼接的活,Java程序员也肯定用到过StringBuffer,StringBuilder,以及被编译器优化掉的+=。但这些都和下文要谈的无关。

直接使用"+"拼接比较多的字符串,变量一多,可读性就下降,出错的几率就增加,并且难以维护。

需要拼接的变量比较多时,可以使用MessageFormat.format。

示例:

String[] tdArr={...};

String result=MessageFormat.format("

{0}{1}{2}{3}", tdArr);

这段代码将把数组tdArr中的四个元素分别插入到{0},{1},{2},{3}的位置。

你看看,是不是这样形式和内容有效的分开了。容易想象,当元素增多时,这种方式优势很明显。

一件事有很多手段来达成,知道那种手段更好,是你经验的体现和专业化的特征。

使用下标来决定拼接的位置,第一个参数的下标为0,pattern中下标的位置是不要求是顺序的

public static voidmain(String[] args) {

String longitude= "1.0";

String latitude= "2.0";

String result= "result";

String geoCode= "geoCode";

String format1= MessageFormat.format("longitude:{0},latitude:{1}, body:{2},reGeoCode:{3}", longitude, latitude, result, geoCode);

System.out.println(format1);

String format2= MessageFormat.format("longitude:{3},latitude:{2}, body:{1},reGeoCode:{0}", longitude, latitude, result, geoCode);

System.out.println(format2);

String format3= MessageFormat.format("longitude:{2},latitude:{3}, body:{0},reGeoCode:{1}", longitude, latitude, result, geoCode);

System.out.println(format3);

}

输出:

longitude:1.0,latitude:2.0, body:result,reGeoCode:geoCode

longitude:geoCode,latitude:result, body:2.0,reGeoCode:1.0

longitude:result,latitude:geoCode, body:1.0,reGeoCode:2.0

java.text.MessageFormat格式化字符串时的小技巧

public static void main(String[] args) throwsInterruptedException {

MessageFormat form= newMessageFormat("{2,date,yyyy-MM-dd HH:mm:ss.SSS} The disk \"{1}\" contains {0,number,#.##} file(s).{3}");int fileCount = 1273273237;

String diskName= "MyDisk";

Object[] testArgs= {new Long(fileCount), diskName, new Date(),newDate()};

System.out.println(form.format(testArgs));

}

执行结果:2016-05-26 13:41:59.162 The disk "MyDisk" contains 1273273237 file(s).16-5-26 下午1:41

如果缺少ArgumentIndex 则会报错:

java.lang.IllegalArgumentException: can't parse argument number:

at java.text.MessageFormat.makeFormat(MessageFormat.java:1429)

at java.text.MessageFormat.applyPattern(MessageFormat.java:479)

at java.text.MessageFormat.(MessageFormat.java:362)

at java.text.MessageFormat.format(MessageFormat.java:840)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值