JDK1.5新特性,基础类库篇,格式化类(Formatter)用法
Formatter类提供了对布局对齐和排列的支持,以及对数值、字符串和日期、时间数据的常规格式和特定于语言环境的输出的支持。通用Java类型,诸如byte、BigDecimal和Calendar都被支持。
Java语言格式化后的字符串很像C语言的printf函数,但比C语言严谨,比如,C语言忽略无效参数,而Java则会抛出异常。同时它也不是为多线程设计的,程序员需要自己考虑同步的问题。
一. 语法
1. 常规类型、字符类型和数值类型的格式说明符语法如下:
%[argument_index$][flags][width][.precision]conversion
2. 用来表示日期和时间类型的格式说明符语法如下:
%[argument_index$][flags][width]conversion
3. 与参数不对应的格式说明符语法如下:
%[flags][width]conversion
-argument_index 可选参数,是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 表示,第二个参数由 "2$" 表示,依此类推。
-flags 可选参数,是修改输出格式的字符集。有效标志集取决于转换类型。
-width 可选参数,是一个非负十进制整数,表明要向输出中写入的最少字符数。
-precision 可选参数,是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。
-conversion 必须参数,是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。
二. 参数详解
1. Argument Index
是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 表示,第二个参数由 "2$" 表示,依此类推。
2. Flags
| Flag | General | Character | Integral | Floating Point | Date/Time | Description |
| '-' | y | y | y | y | y | 结果将是左对齐的 |
| '#' | y1 | - | y3 | y | - |
结果应该使用依赖于转换类型的替换形式 |
| '+' | - | - | y4 | y | - |
结果总是包括一个符号 |
| ' ' | - | - | y4 | y | - |
对于正值,结果中将包括一个前导空格 |
| '0' | - | - | y | y | - |
结果将用零来填充 |
| ',' | - | - | y2 | y5 | - | 结果将包括特定于语言环境的组分隔符 |
| '(' | - | - | y4 | y5 | - |
结果将是用圆括号括起来的负数 |
y1 取决于 Formattable 的定义。
y2 只适用于 'd' 转换。
y3 只适用于 'o'、'x' 和 'X' 转换。
y4 对 BigInteger 应用 'd'、'o'、'x' 和 'X' 转换时,或者对 byte 及 Byte、short 及 Short、int 及 Integer、long 及 Long 分别应用 'd' 转换时适用。
y5 只适用于 'e'、'E'、'f'、'g' 和 'G' 转换。
任何未显式定义为标志的字符都是非法字符,并且都被保留,以供扩展使用。
3. Width
width表示输出字符的最少字符数。被格式化参数用precision截取器截取后与width相比,被格式化参数字符数如果小于width,则加字符则到width。在行分隔符转换(line separator conversion)中,width被禁止使用。
4. Precision
- 对于常规类型,precision表示输出字符的最大字符数。
- 对浮点类型转换'e', 'E',和'f',precision小数点的几位数字。如果转换是'g'或'G',precision表示取整后的全部数字。如果转换是'a'或'A',precision被禁止使用。
- 对字符、整型的、日期和时间类型,precision被禁止使用。
5. Conversions
转换字符大致可分为如下几类:
- 常规(General)- 可应用于任何参数类型
- 字符(Character)- 可应用于表示 Unicode 字符的基本类型:char、Character、byte、Byte、short 和 Short。当 Character.isValidCodePoint(int) 返回 true 时,可将此转换应用于 int 和 Integer 类型。
- 数值(Numeric)
1)整数(Integral)- 可应用于 Java 的整数类型:byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger
2)浮点(Floating Point)- 可用于 Java 的浮点类型:float、Float、double、Double 和 BigDecimal - 日期/时间(Date/Time)- 可应用于 Java 的、能够对日期或时间进行编码的类型:long、Long、Calendar 和 Date
- 百分比(Percent)- 产生字面值 '%' ('\u0025')
- 行分隔符(Line Separator)- 产生特定于平台的行分隔符
大写转换符(也就是: 'B', 'H', 'S', 'C', 'X', 'E', 'G', 'A', and 'T')在功能上与其小写是一样的,只不过在输出时将结果转换为大写。相当于对结果调用:String.toUpperCase()。
| Conversion | Argument Category | Description |
| 'b', 'B' | 常规(General) | 如果参数 arg 为 null,则结果为 "false"。如果 arg 是一个 boolean 值或 Boolean,则结果为 String.valueOf() 返回的字符串。否则结果为 "true"。 |
| 'h', 'H' | 常规(General) | 如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode()) 得到的结果。 |
| 's', 'S' | 常规(General) | 如果参数 arg 为 null,则结果为 "null"。如果 arg 实现 Formattable,则调用 arg.formatTo。否则,结果为调用 arg.toString() 得到的结果。 |
| 'c', 'C' | 字符(Character) |
结果是一个 Unicode 字符 |
| 'd' | 整数(Integral) |
结果被格式化为十进制整数 |
| 'o' | 整数(Integral) |
结果被格式化为八进制整数 |
| 'x', 'X' | 整数(Integral) |
结果被格式化为十六进制整数 |
| 'e', 'E' | 浮点(Floating Point) |
结果被格式化为用计算机科学记数法表示的十进制数 |
| 'f' | 浮点(Floating Point) | 结果被格式化为十进制数 |
| 'g', 'G' | 浮点(Floating Point) | 结果被格式化为十进制数 |
| 'a', 'A' | 浮点(Floating Point) |
结果被格式化为带有效位数和指数的十六进制浮点数 |
| 't', 'T' | 日期/时间(Date/Time) |
日期和时间转换字符的前缀,后缀参考下面的时间、日期转换字符 |
| '%' | 百分比(Percent) |
结果为字面值 '%' |
| 'n' | 行分隔符(Line Separator) |
结果为特定于平台的行分隔符 |
下面三张表分别表示日期、时间、通用转换字符后缀。作为上表't','T'转换字符的补充。
5.1 时间转换字符
| 'H' | 两位数表示的24小时制时间格式,也就是:00-23 |
| 'I' | 两位数表示的12小时制时间格式,也就是:01-12 |
| 'k' | 24小时制时间格式,也就是:0-23 |
| 'l' | 12小时制时间枨,也就是1-12 |
| 'M' | 两位数表示的分钟格式,也就是:00-59 |
| 'S' | 两位数表示的秒格式,也就是:00-60(("60" is a special value required to support leap seconds) |
| 'L' | 三位数表示的毫秒格式,也就是:000-999 |
| 'N' | 九位数表示的纳秒格式,也就是:000000000-999999999 |
| 'p' | 与区域(Locale)相关的上下午标志,如:am/pm |
| 'z' | RFC 822 样式时差设置,如:-0800 |
| 'Z' | 表示时区的字符串,代替默认时区 |
| 's' | 从1 January 1970 00:00:00 UTC到现在秒数 |
| 'Q' | 从1 January 1970 00:00:00 UTC到现在的毫秒数 |
5.2 日期转换字符
| 'B' | 区域相关的月分名称,如:"January", "February". |
| 'b' | 区域相关的月分名称缩写,如:"Jan", "Feb". |
| 'h' | 同'b' |
| 'A' | 区域相关的星期几,如:"Sunday", "Monday" |
| 'a' | 区域相关的星期几缩写,如:"Sun", "Mon" |
| 'C' | 两位表示四位年数除以100的值,也就是:00-99 |
| 'Y' | 至少四位数字表示的年份 |
| 'y' | 两位数字表示的年份,也就是:00-99 |
| 'j' | 一年中的第几天,也就是:001-366 |
| 'm' | 两位数字表示的月份,也就是:01-12 |
| 'd' | 两位数字表示的该月第几天,也就是:01-31 |
| 'e' | 该月第几天,也就是:1-31 |
5.3 日期与时间通用转移字符
| 'R' | 时间格式化为24小时制,"%tH:%tM" |
| 'T' | 时间格式化为24小时制,"%tH:%tM:%tS" |
| 'r' | 时间格式化为12小时制,"%tI:%tM:%tS %Tp" |
| 'D' | 日期格式化为"%tm/%td/%ty" |
| 'F' | ISO 8601完整日期格式为"%tY-%tm-%td" |
| 'c' | 日期时间格式为"%ta %tb %td %tT %tZ %tY",如:"Sun Jul 20 16:17:00 EDT 1969" |
所有在上述日期与时间转换字符中未显式定义为转换字符的字符都将被视为非法字符,被予以保留,以供扩展使用。
三. 示范代码
System.out.format,System.err.printf,String.format都是通用Formatter实现的。
package com.clzhang.sample.thinking; import java.io.*;
import java.util.*;
import static java.util.Calendar.*; import org.junit.Test; // System.out.format,System.err.printf,String.format都是通用Formatter实现的。
public class JDK15Formatter {
@Test
public void testFormatter() {
Formatter formatter = new Formatter(System.out); // 倒序输出各参数
// %4$表示参数位置;2表示宽度;s表示toString输出。
formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
System.out.println();
// -> " d c b a" // 可选区域参数作为第一个参数,可以用来格式化区域相关的格式数字;precision与width参数用来取整与对齐值。
// Locale.CHINA为区域参数;%参数;+表示结果总包括一个符号;10表示宽度(不够补空格);.4表示小数点后位数;f表示结果被格式化为十进制数
formatter.format(Locale.CHINA, "e = %+10.4f", Math.E);
System.out.println();
// -> "e = +2,7183" // '('数值符号可以用来代替负数符号'-',组分隔符自动插入。
// %参数;(表示圆括号括起来的是负数;,组分隔符;.2表示小数点后保留两位;f表示结果被格式化为十进制数
double balanceDelta = -6217.58231;
formatter.format("Amount gained or lost since last statement: $ %(,.2f", balanceDelta);
System.out.println();
// -> "Amount gained or lost since last statement: $ (6,217.58)" // Writes a formatted string to System.out.
System.out.format("Local time: %tT", Calendar.getInstance());
System.out.println();
// -> Local time: 14:38:39 // Writes formatted output to System.err.
String filename = "C:\\notexists\\food.txt";
File file = new File(filename);
try {
if(!file.exists())
throw new IOException("文件不存在!");
} catch (Exception e) {
System.err.printf("Unable to open file '%1$s': %2$s", filename, e.getMessage());
System.err.println();
// -> Unable to open file 'C:\notexists\food.txt': 文件不存在!
} // Format a string containing a date.
Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
System.out.println(s);
// -> Duke's Birthday: 05 23,1995 formatter.close();
}
}
JDK1.5新特性,基础类库篇,格式化类(Formatter)用法的更多相关文章
- JDK1.5新特性,语言篇
Java 1.5版本,就是Java 2 Standard Edition 5,Version 1.5,简称Java 5.版本代号Tiger. 一. 泛型(Generics) C++通过模板技术可以指定 ...
- JDK1.7新特性,语言篇
1. 可以用二进制表达数字 可以用二进制表达数字(加前缀0b/0B),包括:byte, short, int, long // 可以用二进制表达数字(加前缀0b/0B),包括:byte, short, ...
- JDK1.5新特性,基础类库篇,集合框架(Collections)
集合框架在JDK1.5中增强特性如下: 一. 新语言特性的增强 泛型(Generics)- 增加了集合框架在编译时段的元素类型检查,节省了遍历元素时类型转换代码量. For-Loop循环(Enhanc ...
- jdk1.6新特性
1.Web服务元数据 Java 里的Web服务元数据跟微软的方案基本没有语义上的区别,自从JDK5添加了元数据功能(Annotation)之后,SUN几乎重构了整个J2EE体 系, 由于变化很大,干脆 ...
- Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27
Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27 1. 修改历史2 2. 适用语言::几乎所有编程语言.语言提升的三个渠道::语法,类库,框架,ide2 2.1. 单根继承 ...
- JDK1.8新特性——Collector接口和Collectors工具类
JDK1.8新特性——Collector接口和Collectors工具类 摘要:本文主要学习了在Java1.8中新增的Collector接口和Collectors工具类,以及使用它们在处理集合时的改进 ...
- JDK1.8新特性——Stream API
JDK1.8新特性——Stream API 摘要:本文主要学习了JDK1.8的新特性中有关Stream API的使用. 部分内容来自以下博客: https://blog.csdn.net/icarus ...
- JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用
jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default Lambda表达式 L ...
- JDK1.8新特性之(三)--函数式接口
在上一篇文章中我们介绍了JDK1.8的新特性有以下几项. 1.Lambda表达式 2.方法引用 3.函数式接口 4.默认方法 5.Stream 6.Optional类 7.Nashorm javasc ...
- JDK1.8新特性之(一)--Lambda表达式
近期由于新冠疫情的原因,不能出去游玩,只能在家呆着.于是闲来无事,开始阅读JDK1.8的源代码.在开始之前也查询了以下JDK1.8的新特性,有针对性的开始了这段旅程. 只看不操作,也是不能心领神会的. ...
随机推荐
- [Node.js]22. Level 4: Dependency
Add two dependencies to your package.json file, connect and underscore. You'll want to useconnect ve ...
- android设置横屏和竖屏的方法
方法一:在AndroidManifest.xml中配置 假设不想让软件在横竖屏之间切换,最简单的办法就是在项目的AndroidManifest.xml中找到你所指定的activity中加上androi ...
- 免费资源:JellyFish的iOS8应用图标集
本地下载 包含设计和PNG效果图片的iOS8的图标集合.
- Android studio 2.0--android增量更新的那些事
用了这么久的AS 2.0预览版本号.4.7日谷歌最终公布了android studio 2.0正式版,小编当日便下载了.玩了一下.感觉第二次build编译明显快了,并且好像并没有又一次部署apk.经过 ...
- Websocket——Websocket原理
偶然在知乎上看到一篇回帖,瞬间认为之前看的那么多资料都不及这一篇回帖让我对 websocket 的认识深刻有木有.所以转到我博客里,分享一下.比較喜欢看这样的博客,读起来非常轻松.不枯燥,没有布道师的 ...
- rpm常用命令及rpm参数介绍
RPM是RedhatPackageManager的缩写,是由RedHat公司开发的软件包安装和管理程序,同Windows平台上的Uninstaller比较类似.使用RPM,用户可以自行安装和管理Lin ...
- vue diff算法 patch
1.diff比较算法 图示: diff比较只会在同层级进行, 不会跨层级比较. 所以diff是:广度优先算法. 时间复杂度:O(n) 代码示例: <!-- 之前 --> <div&g ...
- 〖Windows〗zigbee实验之cygwin编译tinyos.jar编译出错的解决方法
1. 使用的cygwin安装包下载地址:cygwin-files.zip 2. 使用的一些rpm安装包的下载地址:cygwin_cc2430_rpms.zip 3. cygwin的默认安装目录是:C: ...
- 身份证查询API
# -*- coding: utf-8 -*- #python 27 #xiaodeng #http://apistore.baidu.com/apiworks/servicedetail/113.h ...
- java 内省(Introspector)
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性. 当然你也可以用反射来操作JavaB ...