MessageFormat用法:占位符{0}

一、前言                              

  刚开始从.net的转向java的时候总觉得 String.format 用得不习惯,希望格式模版会这样 {0}, this is {1}'s cat.{1},this is {0}'s dog. 而不是 %1$s,this is %2$s's cat.%2$s,this is %1$s's dog. 。后来发现 java.text.MessageFormat.format 可以满足我这个小小的愿望。

 

二、静态方法 java.text.MessageFormat.format                 

  方法定义:

String MessageFormat.format(String fmt, Object...args)

  入参fmt为MessageFormat模式参数。

 

三、MessageFormat模式                      

  格式:  ArgumentIndex[,FormatType[,FormatStyle]] 

  ArgumentIndex ,是从0开始的入参位置索引。

  FormatType ,指定使用不同的Format子类对入参进行格式化处理。值范围如下:

     number:调用NumberFormat进行格式化

     date:调用DateFormat进行格式化

     time:调用DateFormat进行格式化

     choice:调用ChoiceFormat进行格式化

  FormatType ,设置FormatType中使用的格式化样式。值范围如下:

    short,medium,long,full,integer,currency,percent,SubformPattern(子格式模式,形如#.##)

  注意: FormatType 和 FormatStyle 主要用于对日期时间、数字、百分比等进行格式化。

  示例——将数字1.23格式为1.2:

double num = 1.23;
String str = MessageFormat.format("{0,number,#.#}", num);

 

四、MessageFormat注意点                    

  1. 两个单引号才表示一个单引号,仅写一个单引号将被忽略。

  2. 单引号会使其后面的占位符均失效,导致直接输出占位符。

MessageFormat.format("{0}{1}", 1, 2); // 结果12
MessageFormat.format("'{0}{1}", 1, 2); // 结果{0}{1}
MessageFormat.format("'{0}'{1}", 1, 2); // 结果{0}

因此可以用于输出左花括号(单写左花括号会报错,而单写右花括号将正常输出)

MessageFormat.format("'{'{0}}", 2); // 结果{2

因此前言中的示例应该写为

{0}, this is {1}''s cat.{1},this is {0}''s dog.

 

五、类层级关系                                

                                         |-- java.text.MessageFormat

顶层抽象类java.text.Format—|                                         |--java.text.ChoiceFormat

                                         |--java.text.NumberFormat—|

               |               |--java.text.DecimalFormat

               |

                                         |--java.text.DateFormat—java.text.SimpleDateFormat

   1. DecimalFormat

       用于格式化十进制实数。通过格式字符串来自定义格式化类型,舍入方式为half-even(四舍五入)。

       格式化模式: 正数子模式;负数子模式 ,如 0.00;-0.00 ,简写为 0.00 。

       模式中的占位符:

     0 ,代表该为位为数字,若不存在则用0填充

         # ,代表该为位为数字

     , ,代表分隔符, 如模式为 #,# ,那么格式化10时会返回1,0

   2. ChoiceFormat

    相当于以数字为键,字符串为值的键值对。分别使用一组double类型的数组作为键,一组String类型的数组作为值,两数组相同索引值的元素作为一对。

    示例——基本用法

复制代码
double[] limit = {0,1,3};
String[] format = {"hello0", "hello1", "hello3"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
for(int i = 0; i < 4; ++i){
  System.out.println(cf.format(i));
}
/* 输出
 * hello0
 * hello1
 * hello0
 * hello3
 */
复制代码

   注意:当找不到对应的键值对时,则使用第一或最后一对键值对。

   示例——结合MessageFormat使用

复制代码
double[] limit = {0, 1};
String[] format = {"Hello0", "Hello1{1}"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
MessageFormat mf = new MessageFormat("{0}");
mf.setFormatByArgumentIndex(0, cf);
for (int i = 0; i < 2; ++i){
    System.out.println(mf.format(new Object[]{new Integer(i), new Integer(i+1)}));
}
/* 输出
 * Hello0
 * Hello12
 */
复制代码

 

六、性能问题                                  

  由于静态方法 MessageFormat.format 内部是

public static String format(String pattern, Object ... arguments)   
{  
    MessageFormat temp = new MessageFormat(pattern);  
    return temp.format(arguments);  
}  

  因此若要多次格式同一个模式的字符串,那么创建一个MessageFormat实例在执行格式化操作比较好些。

 

七、总结                                  

  对于简单的格式化或字符串组装, MessageFormat.format方法 使用更方便些,但要格式化处理更丰富的话要是用 String.format方法 吧!  

  尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4095059.html  ^_^肥仔John  


---------------------------------------------------------------------------------------------------------------------------------------

MessageFormat用来格式化一个消息,通常是一个字符串,比如:

String str = "I'm not a {0}, age is {1,number,short}", height is {2,number,#.#};

 

MessageFormat可以格式化这样的消息,然后将格式化后的字符串插入到模式中的适当位置,比如:

将str中的{0}用"pig"替换,{1,number,short}用数字8替换,{2,number,#.#}用数字1.2替换。

那么最终用户得到的是一个格式化好的字符串"I'm not a pig, age is 8, height is 1.2"。

 

MessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息。

 

MessageFormat模式(主要部分): 

 

FormatElement:
         { ArgumentIndex }
         { ArgumentIndex , FormatType }
         { ArgumentIndex , FormatType , FormatStyle }

 

 FormatType
         number

         date

         time

         choice(需要使用ChoiceFormat

 

 FormatStyle:
         short
         medium
         long
         full
         integer
         currency
         percent
         SubformatPattern(子模式)

 

还以str为例,在这个字符串中:

1、{0}和{1,number,short}和{2,number,#.#};都属于FormatElement0,1,2是ArgumentIndex。

2、{1,number,short}里面的number属于FormatTypeshort则属于FormatStyle

3、{1,number,#.#}里面的#.#就属于子格式模式。

 

指定FormatTypeFormatStyle是为了生成日期格式的值、不同精度的数字、百分比类型等等。

 

实例:

1、ArgumentIndex必须是非负整数,它的个数不只限于0到9这10个,它可以用0到9的数字组成,因此可以有好多个,如:

Java代码   收藏代码
  1. String pig = "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}";  
  2.   
  3. Object[] array = new Object[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

最终结果是:ABCDEFGHIJKLMNOPQ

 

2、格式化字符串时,两个单引号才表示一个单引号,单个单引号会被省略,如:

Java代码   收藏代码
  1. String message = "oh, {0} is 'a' pig";  
  2.   
  3. Object[] array = new Object[]{"ZhangSan"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, ZhangSan is a pig

 

给字母a加上单引号,如:

Java代码   收藏代码
  1. String message = "oh, {0} is ''a'' pig";  
  2.   
  3. Object[] array = new Object[]{"ZhangSan"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, ZhangSan is 'a' pig

 

3、单引号会使某个字符或串保持原形。

     所以,假如没有特殊要求,一般都是要在正式格式化之前把单引号都去掉,否则会造成不必要的麻烦,如:

Java代码   收藏代码
  1. String message = "oh, '{0}' is a pig";  
  2.   
  3. Object[] array = new Object[]{"ZhangSan"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, {0} is 'a' pig,此处ZhangSan无法显示。

 

 又如,使用子格式模式,多了一个单引号:

Java代码   收藏代码
  1. String message = "oh, '{0,number,#.#} is a pig";  
  2.   
  3. Object[] array = new Object[]{new Double(3.1415)};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, {0,number,#.#}  is 'a' pig。

 

 如果像下面这样,就可以正确显示:

Java代码   收藏代码
  1. String message = "oh, {0,number,#.#} is a pig";  
  2.   
  3. Object[] array = new Object[]{new Double(3.1415)};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, 3.1 is a pig

 

3、无论是有引号字符串还是无引号字符串,左花括号都是不支持的,但支持右花括号显示,如:

Java代码   收藏代码
  1. String message = "oh, { is a pig";  
  2.   
  3. Object[] array = new Object[]{"ZhangSan"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:异常java.lang.IllegalArgumentException: Unmatched braces in the pattern

 

右花括号可以显示,如:

Java代码   收藏代码
  1. String message = "oh, } is a pig";  
  2.   
  3. Object[] array = new Object[]{"ZhangSan"};  
  4.   
  5. String value = MessageFormat.format(message, array);  
  6.   
  7. System.out.println(value);  

 最终结果是:oh, } is a pig

 

 

关于MessageFormat.format方法:

每调用一次MessageFormat.format方法,都会新创建MessageFormat的一个实例,相当于MessageFormat只使用了一次。MessageFormat类的format方法如下:

Java代码   收藏代码
  1. public static String format(String pattern, Object ... arguments)   
  2. {  
  3.     MessageFormat temp = new MessageFormat(pattern);  
  4.     return temp.format(arguments);  
  5. }  

 

如果要重复使用某个MessageFormat实例,可以用如下方式:

Java代码   收藏代码
  1. String message = "oh, {0} is a pig";  
  2.   
  3. MessageFormat messageFormat = new MessageFormat(message);  
  4.   
  5. Object[] array = new Object[]{"ZhangSan"};  
  6.   
  7. String value = messageFormat.format(array);  
  8.   
  9. System.out.println(value);  

 最终结果是:oh, ZhangSan is a pig




在Java程序中做字符串拼接时一定要记得的MessageFormat.format

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

比如有这样的字符串:

张三将去某地点找李四。

其中,张三某地点和李四都是可变的,比如张三变成王五,某地点变成纽约,李四变成赵六。于是整句变成:

王五将去纽约找赵六。

如果直接将张三,某地点和李四用变量替代,再拼接起来,可以达到目的。但是,代码不好写,也不好看,也不好维护。但是,我看过很多SQL拼接,HTML拼接都是这样做的。我自己以前也是这样,自从接触了MessageFormat.format之后才意识到有更好的形式。请看下面的代码:

String[] tdArr=...;            
String result=MessageFormat.format("<tr bgcolor='#cef'><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", tdArr);

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

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

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

补记:

如果字符串需要输出单引号',可以用两个单引号''进行转义,下面代码请参考:

public int insertToTest_tb(String createTime,String datefrom,String dateto,String name,String intranetid,String actualhour,String planhour,String status) throws Exception{
        StringBuilder sb=new StringBuilder();
        sb.append("    insert into test_tb (");
        sb.append("        createTime, ");
        sb.append("        datefrom, ");
        sb.append("        dateto, ");
        sb.append("        name, ");
        sb.append("        intranetid, ");
        sb.append("        actualhour, ");
        sb.append("        planhour, ");
        sb.append("        status");
        sb.append("    ) values (");
        sb.append("        ''{0}'',");
        sb.append("        ''{1}'',");
        sb.append("        ''{2}'',");
        sb.append("        ''{3}'',");
        sb.append("        ''{4}'',");
        sb.append("        ''{5}'',");
        sb.append("        ''{6}'',");
        sb.append("        ''{7}''");
        sb.append("    )");
        String result=sb.toString();
        
        Object[] arr={createTime,datefrom,dateto,name,intranetid,actualhour,planhour,status};
        String sql=MessageFormat.format(result, arr);
        
        return this.getJdbcTemplate().update(sql);
    }


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,可以使用MessageFormat类来处理占位符。首先,需要导入java.text.MessageFormat类。然后,可以使用MessageFormat.format方法来替换占位符。例如,可以使用以下代码来替换占位符并打印输出结果: ```java import java.text.MessageFormat; public class Test { public static void main(String\[\] args) { String url = "www.baidu.com"; int count = 1000; String message = MessageFormat.format("该网站{0}被访问了 {1} 次.", url, count); System.out.println(message); } } ``` 输出结果为:该网站www.baidu.com被访问了 1,000 次. \[2\] 如果你想在生成HTML模板中使用占位符,可以按照以下步骤操作: 1. 根据资源中的生成HTML操作手册制作HTML模板。\[3\] 2. 将生成的模板放在项目本地或者运城OSS存储中。 3. 使用Java代码将业务数据替换占位符,并生成PDF。 4. 如果在操作过程中遇到问题,可以在资源的README.md中找到博主的私人联系方式。\[3\] #### 引用[.reference_title] - *1* *2* [Java输出格式化之占位符](https://blog.csdn.net/weixin_35389904/article/details/114200035)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Word制作生成html模板替换动态值为占位符使用Java转为pdf文件](https://blog.csdn.net/zl5186888/article/details/126814772)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值