提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- java.text.Format体系
- 1.DateFormat:日期时间格式化
- SimpleDateFormat
- 2.NumberFormat:数字格式化
- DecimalFormat
- 3.MessageFormat:字符串格式化
- 简单案例
- 2.参数模式
- 3.注意事项
- 4.经典使用场景
- 5.特殊使用
- 数字
- 日期
- 时间
- 在结论上补充其他更加特殊情况
java.text.Format体系
在日常开发中,我们经常会有格式化的需求,如日期格式化、数字格式化、钱币格式化等等。
格式化器的作用似乎跟转换器的作用类似,但是它们的关注点却不一样:
- 转换器:将类型S转换为类型T,关注的是类型而非格式
- 格式化器: String <-> Java类型。这么一看它似乎和PropertyEditor类似,但是它的关注点是字符串的格式
Java里从来都缺少不了字符串拼接的活,JDK也提供了多种“工具”供我们使用,如:StringBuffer、StringBuilder以及最直接的+号,相信这些大家都有用过。但这都不是本文的内容,本文将讲解格式化器,给你提供一个新的思路来拼接字符串,并且是推荐方案。
JDK内置有格式化器,便是java.text.Format体系。它是个抽象类,提供了两个抽象方法:
public abstract class Format implements Serializable, Cloneable {public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos); public abstract Object parseObject (String source, ParsePosition pos);
}
- format:将Object格式化为String,并将此String放到toAppendTo里面
- parseObject:讲String转换为Object,是format方法的逆向操作
1.DateFormat:日期时间格式化
抽象类。用于用于格式化日期/时间类型java.util.Date。虽然是抽象类,但它提供了几个静态方法用于获取它的实例:
// 格式化日期 + 时间
public final static DateFormat getInstance() {return getDateTimeInstance(SHORT, SHORT);
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale){return get(timeStyle, dateStyle, 3, aLocale);
}// 格式化日期
public final static DateFormat getDateInstance(int style, Locale aLocale) {return get(0, style, 2, aLocale);
}
// 格式化时间
public final static DateFormat getTimeInstance(int style, Locale aLocale){return get(style, 0, 1, aLocale);
}
有了这些静态方法,你可在不必关心具体实现的情况下直接使用:
@Testpublic void test1() {Date curr = new Date();// 格式化日期 + 时间System.out.println(DateFormat.getInstance().getClass() + "-->" + DateFormat.getInstance().format(curr));System.out.println(DateFormat.getDateTimeInstance().getClass() + "-->" + DateFormat.getDateTimeInstance().format(curr));// 格式化日期System.out.println(DateFormat.getDateInstance().getClass() + "-->" + DateFormat.getDateInstance().format(curr));// 格式化时间System.out.println(DateFormat.getTimeInstance().getClass() + "-->" + DateFormat.getTimeInstance().format(curr));}
SimpleDateFormat
一般来说,我们会直接使用SimpleDateFormat来对Date进行格式化,它可以自己指定Pattern,个性化十足。如:
2.NumberFormat:数字格式化
抽象类。用于格式化数字,它可以对数字进行任意格式化,如小数、百分数、十进制数等等。它有两个实现类:
@Testpublic void test41() {double myNum = 1220.0455;System.out.println(NumberFormat.getInstance().getClass() + "-->" + NumberFormat.getInstance().format(myNum));System.out.println(NumberFormat.getCurrencyInstance().getClass() + "-->" + NumberFormat.getCurrencyInstance().format(myNum));System.out.println(NumberFormat.getIntegerInstance().getClass() + "-->" + NumberFormat.getIntegerInstance().format(myNum));System.out.println(NumberFormat.getNumberInstance().getClass() + "-->" + NumberFormat.getNumberInstance().format(myNum));System.out.println(NumberFormat.getPercentInstance().getClass() + "-->" + NumberFormat.getPercentInstance().format(myNum));}
DecimalFormat
Decimal:小数,小数的,十进位的。
用于格式化十进制数字。它具有各种特性,可以解析和格式化数字,包括:西方数字、阿拉伯数字和印度数字。它还支持不同种类的数字,包括:整数(123)、小数(123.4)、科学记数法(1.23E4)、百分数(12%)和货币金额($123)。所有这些都可以进行本地化。
说明:Number和Digit的区别:
- Number是个抽象概念,其表达形式可以是数字、手势、声音等等。如1024就是个number
- Digit是用来表达的单独符号。如0-9这是个digit就可以用来表示number,如1024就是由1、0、2、4这四个digit组成的
@Testpublic void test4() {double myNum = 1220.0455;System.out.println("===============0的使用===============");System.out.println("只保留整数部分:" + new DecimalFormat("0").format(myNum));System.out.println("保留3位小数:" + new DecimalFormat("0.000").format(myNum));System.out.println("整数部分、小数部分都5位。不够的都用0补位(整数高位部,小数低位补):" + new DecimalFormat("00000.00000").format(myNum));System.out.println("===============#的使用===============");System.out.println("只保留整数部分:" + new DecimalFormat("#").format(myNum));System.out.println("保留2为小数并以百分比输出:" + new DecimalFormat("#.##%").format(myNum));// 非标准数字(不建议这么用)System.out.println("===============非标准数字的使用===============");System.out.println(new DecimalFormat("666").format(myNum));System.out.println(new DecimalFormat(".6666").format(myNum));}
3.MessageFormat:字符串格式化
MessageFormat提供了一种与语言无关(不管你在中国还是其它国家,效果一样)的方式生成拼接消息/拼接字符串的方法。使用它来构造显示给最终用户的消息。MessageFormat接受一组对象,对它们进行格式化,然后在模式的适当位置插入格式化的字符串。
简单案例
先来个最简单的使用示例体验一把:
@Testpublic void test9() {String sourceStrPattern = "Hello {0},my name is {1}";Object[] args = new Object[]{"girl", "YourBatman"};String formatedStr = MessageFormat.format(sourceStrPattern, args);System.out.println(formatedStr);}
@Testpublic void test9() {String pattern = "当前执行到:{0}{1},下一个执行第{2}{3}";for (int i = 0; i < 10; i++) {System.out.println(MessageFormat.format(pattern, new Object[]{i, "次", i + 1, "次"}));}}
2.参数模式
说明:FormatType和FormatStyle只有在传入值为日期时间、数字、百分比等类型时才有可能需要设置,使用得并不多。毕竟:我在外部格式化好后再放进去不香吗?
@Test
public void test10() {MessageFormat messageFormat = new MessageFormat("Hello, my name is {0}. I’am {1,number,#.##} years old. Today is {2,date,yyyy-MM-dd HH:mm:ss}");// 亦可通过编程式 显示指定某个位置要使用的格式化器// messageFormat.setFormatByArgumentIndex(1, new DecimalFormat("#.###"));System.out.println(messageFormat.format(new Object[]{"YourBatman", 24.123456, new Date()}));
}
3.注意事项
下面基于此示例,对MessageFormat的使用注意事项作出几点强调。
@Test
public void test11() {System.out.println(MessageFormat.format("{1} - {1}", new Object[]{1})); // {1} - {1}System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1})); // 输出:1 - {1}System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1, 2, 3})); // 输出:1 - 2System.out.println("---------------------------------");System.out.println(MessageFormat.format("'{0} - {1}", new Object[]{1, 2})); // 输出:{0} - {1}System.out.println(MessageFormat.format("''{0} - {1}", new Object[]{1, 2})); // 输出:'1 - 2System.out.println(MessageFormat.format("'{0}' - {1}", new Object[]{1, 2})); // {0} - 2// 若你数据库值两边都需要''包起来,请你这么写System.out.println(MessageFormat.format("''{0}'' - {1}", new Object[]{1, 2})); // '1' - 2System.out.println("---------------------------------");System.out.println(MessageFormat.format("0} - {1}", new Object[]{1, 2})); // 0} - 2System.out.println(MessageFormat.format("{0 - {1}", new Object[]{1, 2})); // java.lang.IllegalArgumentException: Unmatched braces in the pattern.
}
4.经典使用场景
这个就很多啦,最常见的有:HTML拼接、SQL拼接、异常信息拼接等等。
StringBuilder sb =new StringBuilder();
sb.append("insert into user (");
sb.append(" name,");
sb.append(" accountId,");
sb.append(" zhName,");
sb.append(" enname,");
sb.append(" status");
sb.append(") values (");
sb.append(" ''{0}'',");
sb.append(" {1},");
sb.append(" ''{2}'',");
sb.append(" ''{3}'',");
sb.append(" {4},");
sb.append(")");Object[] args = {name, accountId, zhName, enname, status};// 最终SQL
String sql = MessageFormat.format(sb.toString(), args);
5.特殊使用
- MessageFormat可对时间、日期、数字进行更加特殊格式转化
- 一般使用MessageFormat只会简单的{0},如 str = “test:{0}”,但其实MessageFormat支持的不仅仅是{0},{0}只是其中一个模板写法,其全称模板如下: { ArgumentIndex , FormatType , FormatStyle }
- ArgumentIndex:数字0,1,2
- FormatType:格式化类型,支持:
- FormatStyle:格式化风格,支持
数字
@Testpublic void test1() {// 数字String str = "test:{0,number,currency}";// 结果:test:¥1.20System.out.println(MessageFormat.format(str, 1.2));String str2 = "test:{0,number,percent}";// 结果:test:120%System.out.println(MessageFormat.format(str2, 1.2));String str3 = "test:{0,number,integer}";// 结果:test:1System.out.println(MessageFormat.format(str3, 1.2));}
日期
@Testpublic void test1() {// 日期String str4 = "test:{0,date,short}";// 结果:22-12-17System.out.println(MessageFormat.format(str4, new Date()));String str5 = "test:{0,date,medium}";// 结果:2022-12-17System.out.println(MessageFormat.format(str5, new Date()));String str6 = "test:{0,date,long}";// 结果:2022年12月17日System.out.println(MessageFormat.format(str6, new Date()));String str7 = "test:{0,date,full}";// 结果:2022年12月17日 星期六System.out.println(MessageFormat.format(str7, new Date()));}
时间
public void test1() {// 时间String str4 = "test:{0,time,short}";// 结果:下午2:41System.out.println(MessageFormat.format(str4, new Date()));String str5 = "test:{0,time,medium}";// 结果:14:41:52System.out.println(MessageFormat.format(str5, new Date()));String str6 = "test:{0,time,long}";// 结果:下午02时41分52秒System.out.println(MessageFormat.format(str6, new Date()));String str7 = "test:{0,time,full}";// 结果:下午02时41分52秒 CSTSystem.out.println(MessageFormat.format(str7, new Date()));}
在结论上补充其他更加特殊情况