天气与日历 切换到窄版

 找回密码
 立即注册

QQ登录

只需一步,快速开始

此广告位出租
查看: 543|回复: 0

[Java教程] Java中的format

[复制链接]

3188

主题

4

回帖

3290

积分

管理员

积分
3290
发表于 2024-2-26 16:19:19 | 显示全部楼层 |阅读模式
Java中允许我们对指定的对象进行某种格式化,从而得到我们想要的格式化样式。
1.Format
Foramt是一个抽象基类,其具体子类必须实现
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
--用于将对象格式化为指定模式的字符串

parseObject(String source, ParsePosition pos)
---用于将字符串重新解析为对象

Format的直接子类包括DateFormat、NumberFormat和MessageFormat
2.DateFormat
  • DateFormat根据当前语言环境格式化日期和时间。
  • DateFormat是一个抽象类,所以不能直接new创建实例对象。但该类为我们提供了工厂方法方便我们使用。
①工厂方法:
1.getDateInstance(),获取格式化的日期,输出:2015-12-10
2.getDateTimeInstance(),获取格式化的日期和时间,输出样式:2015-12-10 10:21:41
3.getTimeInstance(),获取格式化的时间,输出样式:10:21:41
4.getInstance(),获取格式化的日期和时间,输出样式:15-12-10 上午10:21
public static void main(String[] args) {
        DateFormat df1 = DateFormat.getDateInstance();
        System.out.println(df1.format(new Date())); // 2020-5-11
        DateFormat df2 = DateFormat.getDateTimeInstance();
        System.out.println(df2.format(new Date())); //2020-5-11 16:33:03
        DateFormat df3 = DateFormat.getTimeInstance();
        System.out.println(df3.format(new Date())); // 16:33:03
        DateFormat df4 = DateFormat.getInstance();
        System.out.println(df4.format(new Date())); // 20-5-11 下午4:33
    }


②设置格式化样式
在这些工厂发放中允许我们传入一个int参数,该参数允许我们设定格式化风格,从而得到我们相对理想的结果。下表中对应了不同的style值和输出样式(这些常量值都在DateFormat类中)
样式值日期时间
SHORT15-12-10上午10:08
MEDIUM2015-12-1010:09:23
LONG2015年12月10日上午10时09分40秒
FULL2015年12月10日 星期四上午10时17分30秒 CST
DEFAULT2015-12-1010:18:07
例:
DateFormat df1 = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println(df1.format(new Date())); // 2020年5月11日


③设置语言环境
可以指定语言环境获取该语言环境下的格式化日期和时间,
//获取加拿大的格式化日期
DateFormat df5 = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.CANADA);
System.out.println(df5.format(new Date())); // 11-May-2020

3.SimpleDateFormat
SimpleDateFormat是DateFormat的一个具体类,它允许我们指定格式模式从而获取我们理想的格式化日期和时间。
通过SimpleDateFormat的构造方法你可以传入一个格式模式字符串或者通过applyPattern(String pattern)方法添加一个格式模式字符串。
对于格式模式字符串,下面列出几个常用的模式元素
字母日期或时间元素示例
y2015
M年中的月份12
w年中的周数50
W月份中的周数02
D年中的天数344
d月份中的天数10
F月份中的星期02
E星期中的天数星期四、Thu
aAM/PM标记下午、PM
H一天中的小时数(0~23)21
k一天中的小时数(1~24)21
Kam/pm中的小时数(0~11)09
ham/pm中的小时数(1~12)09
m小时中的分钟数31
s分钟中的秒数08
S毫秒数716
SimpleDateFormat sp = new SimpleDateFormat("今天是yyyy-MM-dd a E hh:mm:ss,是yyyy年的第DD天,在该月是第dd天");
System.out.println(sp.format(new Date())); // 今天是2020-05-11 下午 星期一 04:59:13,是2020年的第132天,在该月是第11天
// 设置格式化语言为英文
SimpleDateFormat sp2 = new SimpleDateFormat("今天是yyyy-MM-dd a E hh:mm:ss,是yyyy年的第DD天,在该月是第dd天",Locale.ENGLISH);
System.out.println(sp2.format(new Date())); // 今天是2020-05-11 PM Mon 04:57:37,是2020年的第132天,在该月是第11天

4.NumberFormat
NumberFormat根据当前语言环境格式化数字,是一个抽象基类,可以使用工厂方法获取实例对象
①getCurrencyInstance()方法
根据当前语言环境获取货币数值格式
②getInstance()和getNumberInstance()
都会获取到常规数值格式
③getIntegerInstance()
获取常规整数值格式,如果需要格式化的数值为小数,则会将数值四舍五入为最接近的整数
④getPercentInstance()
获取百分比的数值格式
NumberFormat nf1 = NumberFormat.getCurrencyInstance(Locale.CHINA);
System.out.println(nf1.format(123.5)); // ¥123.50
NumberFormat df3 = NumberFormat.getInstance();
System.out.println(df3.format(11.5)); // 11.5
NumberFormat df4 = NumberFormat.getNumberInstance();
System.out.println(df4.format(11.6)); //11.6
NumberFormat df5 = NumberFormat.getIntegerInstance();
System.out.println(df5.format(11.6)); // 12
NumberFormat df6 = NumberFormat.getPercentInstance();
System.out.println(df6.format(0.56)); // 56%

5.DecimalFormat
  • 允许我们指定格式模式获取我们想要的格式化数值
  • DecimalFormat类对于数值的小数部分,默认显示3位小数,在去掉超出小数点后面3位的部分时,会将数值四舍五入为最接近的数值格式化输出
①setMaximumFractionDigits(int newValue)
设置小数部分中允许的最大数字位数
②setMinimumFractionDigits(int newValue)
置小数部分中允许的最小数字位数,如果原数小数位数不够的话,会补零
③setGroupingSize(int i)
设置分组中一组的位数
④setGroupingUsed(boolean value)
设置是否使用分组,true表示使用,false表示取消分组
⑤setMaximumIntegerDigits(int newValue)
设置整数部分允许的最大数字位数
⑥setMinimumIntegerDigits(int newValue)
设置整数部分允许的最小数字位数
  1. public static void main(String[] args) {
  2.     // 默认小数位保留3位
  3.     DecimalFormat df1 = new DecimalFormat();
  4.     System.out.println(df1.format(1.555666)); // 1.556
  5.     // 小数部分最大位数
  6.     DecimalFormat df2 = new DecimalFormat();
  7.     df2.setMaximumFractionDigits(3);
  8.     System.out.println(df2.format(12.66554433)); // 12.666
  9.     // 小数部分最小位数
  10.     DecimalFormat df3 = new DecimalFormat();
  11.     df3.setMinimumFractionDigits(4);
  12.     System.out.println(df3.format(12.23)); // 12.2300
  13.     // 整数部分最大位数
  14.     DecimalFormat df4 = new DecimalFormat();
  15.     df4.setMaximumIntegerDigits(3);
  16.     System.out.println(df4.format(4321.1234)); // 321.123
  17.     // 整数部分最小位数
  18.     DecimalFormat df5 = new DecimalFormat();
  19.     df5.setMinimumIntegerDigits(4);
  20.     System.out.println(df5.format(321.1234)); // 0,321.123
  21.     // 设置分组中一组的位数(数值的整数部分,默认3个数字为一组进行显示)
  22.     DecimalFormat df6 = new DecimalFormat();
  23.     df6.setGroupingSize(2);
  24.     System.out.println(df6.format(10000000)); // 10,00,00,00
  25.     // 是否使用分组,true表示使用,false表示取消分组
  26.     DecimalFormat df7 = new DecimalFormat();
  27.     df7.setGroupingUsed(false);
  28.     System.out.println(df7.format(10000000)); // 10000000
  29. }
复制代码
⑦传入格式模式字符串输出我们想要的格式化数值
字符模式类型表示类型小数位是否补0整数位是否补0
0表示一个数字,被格式化数值不够的位数会补0整数位不足时在高位补0
#表示一个数字,被格式化数值不够的位数不会补0整数位不会变化(限制最多,不限制最少)
%将数值乘以100并显示为百分数
\u2030将数值乘以1000并显示为千分数
.小数点分隔符 的占位符
,分组分隔符 的占位符
例子:
  1. DecimalFormat format1 = new DecimalFormat("#\u2030");
  2. System.out.println(format1.format(0.3345));//输出334‰
  3.         
  4. DecimalFormat format2 = new DecimalFormat("##.##");
  5. System.out.println(format2.format(12.345));//输出12.35
  6.         
  7. DecimalFormat format3 = new DecimalFormat("0000.00");
  8. System.out.println(format3.format(12.345));//输出0012.35
  9.         
  10. DecimalFormat format4 = new DecimalFormat("#.##%");
  11. System.out.println(format4.format(12.345));//输出1234.5%
复制代码
6.ChoiceFormat
将格式化运用到某个范围的数,通常与MessageFormat一同使用
①ChoiceFormat构造方法
ChoiceFormat在构造方法中接收一个format数组和一个limits数组,这两个数组的长度必须相等,例如:
limits = {1,2,3,4,5,6,7}
formats = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}

limits数组: 实际上是个区间,可开可闭,并且必须按升序排列,如果不按升序排列,格式化结果将会不正确,还可以使用\u221E(表示无穷大)。
②ChoiceFormat的匹配公式:
limit[j] <= X <limit[j+1]

公式说明:
  • X表示使用format()方法传入的值,j表示limit数组中的索引。
  • 当上述公式成立时,X匹配j,如果不能匹配,则会根据X是太小还是太大,匹配limits数组的第一个索引或最后一个索引;
  • 然后使用匹配的limits数组中的索引,去formats数组中寻找相同索引的值。
例如:
  1. double[] limits = { 3, 4, 5, 6, 7, 8, 9 };
  2. String[] formats = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
  3. ChoiceFormat cf1 = new ChoiceFormat(limits, formats);
  4. // 3.4满足上面匹配公式 匹配3
  5. System.out.println(cf1.format(3.4)); // 星期一
  6. // -1不满足匹配公式, 并且小于limits区间,则匹配第一个要素3
  7. System.out.println(cf1.format(-1)); // 星期一
  8. // 10不满足匹配公式, 并且大于limits区间,则匹配第一个要素9
  9. System.out.println(cf1.format(10)); // 星期日
  10. // 3.4满足上面匹配公式 匹配7
  11. System.out.println(cf1.format(7)); // 星期五
复制代码
③ChoiceFormat几个常用方法(区间表示)
---nextDouble(double d)
静态方法 查找大于d的最小double值,用在limits数组中,从而使limits数组形成一个右开区间数组
System.out.println(ChoiceFormat.nextDouble(3)); // 3.0000000000000004
limits = {0,1,2,,3,ChoiceFormat.nextDouble(3)} // 表示[0,3)的区间

---previousDouble(double d)
静态方法,查找小于d的最大double值
System.out.println(ChoiceFormat.nextDouble(1)); // 0.9999999999999999
limits = {ChoiceFormat.previousDouble(1),1,2,,3} // 表示(1,3]的区间

---nextDouble(double d, boolean positive)
静态方法,如果positive参数为true,表示查找大于d的最小double值;如果positive参数为false,表示查找小于d的最大double值,这样就可以使limits形成一个左开区间数组。
System.out.println(ChoiceFormat.nextDouble(3,true)); // 3.0000000000000004
System.out.println(ChoiceFormat.nextDouble(1,false)); // 0.9999999999999999

---\u221E
\u221E(表示无穷大)
limits = {0,1,2,,3,\u221E} //表示区间[0,+∞)

④模式字符串
ChoiceFormat类的构造方法也允许我们传入一个模式字符串,format方法会根据这个模式字符串执行格式化操作。一个模式元素的格式如下:
doubleNum [占位符] formatStr      占位符可以使用#、<  、\u2264(<=)

格式说明:
  • 模式字符串中的每个模式元素之间使用"|"分割,"|"前后可以添加空格以美化代码
  • 各doubleNum必须按照升序进行书写,否则会出现java.lang.IllegalArgumentException的运行时异常。
  • 根据doubleNum的数据范围 获得formatStr的值
ChoiceFormat fmt = new ChoiceFormat(
      "-1#is negative| 0#is zero or fraction | 1#is one |1.0<is 1+ |2#is two |2<is more than 2.");
System.out.println("Formatter Pattern : " + fmt.toPattern());
System.out.println("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
System.out.println("Format with -1.0 : " + fmt.format(-1.0));
System.out.println("Format with 0 : " + fmt.format(0));
System.out.println("Format with 0.9 : " + fmt.format(0.9));
System.out.println("Format with 1.0 : " + fmt.format(1));
System.out.println("Format with 1.5 : " + fmt.format(1.5));
System.out.println("Format with 2 : " + fmt.format(2));
System.out.println("Format with 2.1 : " + fmt.format(2.1));
System.out.println("Format with NaN : " + fmt.format(Double.NaN));
System.out.println("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));

输出:
   Format with -INF : is negative
   Format with -1.0 : is negative
   Format with 0 : is zero or fraction
   Format with 0.9 : is zero or fraction
   Format with 1.0 : is one
   Format with 1.5 : is 1+
   Format with 2 : is two
   Format with 2.1 : is more than 2.
   Format with NaN : is negative
   Format with +INF : is more than 2.

实际上在内部,模式字符串还是被转换为limits和formats两个数组。在源码中:
ChoiceFormat(String newPattern)调用了applyPattern(String newPattern)方法,在applyPattern方法中对newPattern字符串进行解析,然后将解析后的数据放置到ChoiceFormat类的两个私有属性double[] choiceLimits和String[] choiceFormats中,然后使用格式化方法即可。
7.MessageFormat.
MessageFormat提供了以语言环境无关的生成连接消息的方式。
①基本结构:
MessageFormatPattern:
         String
         MessageFormatPattern FormatElement String

FormatElement:  // (模式元素)
         { ArgumentIndex }  // ArgumentIndex对象数组中的索引,从0开始
         { ArgumentIndex , FormatType }
         { ArgumentIndex , FormatType , FormatStyle }

FormatType: one of  //()
         number  ---NumberFormat 其子格式对应DecimalFormat
         date    ---DateFormat,其子格式对应SimpleDateFormat
         time    ---DateFormat,其子格式对应SimpleDateFormat
         choice  ---ChoiceFormat

FormatStyle:
         short
         medium
         long
         full
         integer
         currency
         percent
         SubformatPattern(子模式)
         
---解释:
String str = "I'm not a {0}, age is {1,number,short}", height is {2,number,#.#};
在这个字符串中:
1、{0}和{1,number,short}和{2,number,#.#};都属于FormatElement,0,1,2是ArgumentIndex。
2、{1,number,short}里面的number属于FormatType,short则属于FormatStyle。
3、{1,number,#.#}里面的#.#就属于子格式模式。
指定FormatType和FormatStyle是为了生成日期格式的值、不同精度的数字、百分比类型等等。

②使用方式
  1. ---1.使用MessageFormat的静态方法format
  2. MessageFormat.format(String pattern, Object ... arguments)
  3. 如:
  4. /**
  5. * 在这个例子中静态方法format第一个参数是字符串类型的,
  6. * 即模式字符串,第二个参数是个可变参数,实际上就是一个Object类型的数组。
  7. * 在模式字符串中使用"{}"标识一个FormatElement。"{}"中的ArgumentIndex对应Object数组中响应索引处的值。
  8. */
  9. int planet = 7;
  10. String event = "a disturbance in the Force";
  11. String result = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
  12. planet, new Date(), event);
  13. System.out.println(result);
  14. //输出:At 20:39:15 on 2015-12-11, there was a disturbance in the Force on planet 7.

  15. ---2.使用MessageFormat的构造方法传入pattern string(模式字符串),然后调用普通的format方法
  16. 如:
  17. String message = "oh, {0} is a pig";
  18. MessageFormat messageFormat = new MessageFormat(message);
  19. Object[] array = new Object[]{"ZhangSan"};
  20. String value = messageFormat.format(array);
  21. System.out.println(value); // 结果 oh, ZhangSan is a pig

  22. ---3.设置自己的Format对象format这些Object
  23. /**在这个例子中,MessageFormat和ChoiceFormat被结合使用
  24. * MessageFormat类中有3个方法值的我们关注
  25. * 1.setFormatByArgumentIndex(int argumentIndex, Format newFormat)//
  26. * 2.setFormats(Format[] newFormats)
  27. * 3.setFormat(int formatElementIndex, Format newFormat)
  28. * 在这个例子当中,在MessageFormat的模式字符串的FormatElement(即{}中的内容)中
  29. * 索引为0的地方将使用ChoiceFormat的格式去格式化。
  30. * 如果在set的Format中仍具有FormatElement,则会递归调用MessageFormat的format方法。
  31. */
  32. MessageFormat form = new MessageFormat("The disk "{1}" contains {0}.");
  33. double[] filelimits = { 0, 1, 2 };
  34. String[] filepart = { "no files", "one file", "{0,number} files" };
  35. ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
  36. form.setFormatByArgumentIndex(0, fileform);
  37. int fileCount = 1273;
  38. String diskName = "MyDisk";
  39. Object[] testArgs = { new Long(fileCount), diskName };
  40. System.out.println(form.format(testArgs));
  41. //输出:The disk "MyDisk" contains 1,273 files.
复制代码
③单引号问题
a. 两个单引号才表示一个单引号,单个单引号会被省略
  1. String message = "oh, {0} is 'a' pig";  
  2. Object[] array = new Object[]{"ZhangSan"};  
  3. String value = MessageFormat.format(message, array);  
  4. System.out.println(value);  // oh, ZhangSan is a pig  ,单引号被省略

  5. ------给字母a加上单引号,两个单引号表示实际的一个单引号 如:
  6. String message = "oh, {0} is ''a'' pig";   
  7. Object[] array = new Object[]{"ZhangSan"};  
  8. String value = MessageFormat.format(message, array);  
  9. System.out.println(value);   // oh, ZhangSan is 'a' pig
复制代码
b. 单引号会使某个字符或串保持原形
  1. String message = "oh, '{0}' is a pig";   
  2. Object[] array = new Object[]{"ZhangSan"};  
  3. String value = MessageFormat.format(message, array);  
  4. System.out.println(value);  // oh, {0} is a pig  此处ZhangSan无法显示

  5. ---正确方式 用两个单引号''进行转义:
  6. String message = "oh, '{0}' is a pig";   
  7. Object[] array = new Object[]{"ZhangSan"};  
  8. String value = MessageFormat.format(message, array);  
  9. System.out.println(value);  // oh, ZhangSan is a pig
复制代码
c. 不支持左花括号(需要单引号括起来),但支持右花括号显示
  1. String message = "oh, '{'{0} }is a pig";  
  2. Object[] array = new Object[]{"ZhangSan"};  
  3. String value = MessageFormat.format(message, array);  
  4. System.out.println(value); // 输出 oh, {ZhangSan}is a pig
复制代码
8.String.format方法
  1. System.out.printf("3>7的结果是:%b %n", 3>7);
复制代码


相关帖子

扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员5折;永久VIP免费
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
快速回复 返回顶部 返回列表