zoukankan      html  css  js  c++  java
  • Java中强大的format

    Java中强大的format

    Java中强大的format


    原文链接:http://www.jianshu.com/p/c8f16cab35e1#

    Java中允许我们对指定的对象进行某种格式化,从而得到我们想要的格式化样式。

    Format

    首先介绍java.text包中的Format
    Foramt是一个抽象基类,其具体子类必须实现

    format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

    parseObject(String source, ParsePosition pos)

    两个抽象方法。
    format方法用于将对象格式化为指定模式的字符串
    parseObject方法用于将字符串重新解析为对象
    Format的直接子类包括DateFormatNumberFormatMessageFormat。下面一一进行介绍

    1.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
    也许你会发现,在这些工厂发放中允许我们传入一个int参数,该参数允许我们设定格式化风格,从而得到我们相对理想的结果。下表中对应了不同的style值和输出样式(这些常量值都在DateFormat类中)

    样式值 日期 时间
    SHORT 15-12-10 上午10:08
    MEDIUM 2015-12-10 10:09:23
    LONG 2015年12月10日 上午10时09分40秒
    FULL 2015年12月10日 星期四 上午10时17分30秒 CST
    DEFAULT 2015-12-10 10:18:07

    当然你也可以指定语言环境获取该语言环境下的格式化日期和时间,


    DateFormat format = DateFormat.getDateInstance(DateFormat.DEFAULT,Locale.CANADA);//获取加拿大的格式化日期

    也许你要发问了,上面的格式没有我一个想要的啊。那好,这里还有一个好东西

    SimpleDateFormat

    SimpleDateFormatDateFormat的一个具体类,它允许我们指定格式模式从而获取我们理想的格式化日期和时间。
    通过SimpleDateFormat的构造方法你可以传入一个格式模式字符串或者通过applyPattern(String pattern)方法添加一个格式模式字符串。
    对于格式模式字符串,API为我们提供了丰富的模式元素,下面列出几个常用的模式元素

    字母 日期或时间元素 示例
    y 2015
    M 年中的月份 12
    w 年中的周数 50
    W 月份中的周数 02
    D 年中的天数 344
    d 月份中的天数 10
    F 月份中的星期 02
    E 星期中的天数 星期四、Thu
    a AM/PM标记 下午、PM
    H 一天中的小时数(0~23) 21
    k 一天中的小时数(1~24) 21
    K am/pm中的小时数(0~11) 09
    h am/pm中的小时数(1~12) 09
    m 小时中的分钟数 31
    s 分钟中的秒数 08
    S 毫秒数 716

    如果你设置Locale的话,会有不同的显示格式,比如如果设置Locale.ENGLISH,E会显示为英文格式,a显示为AM或PM


    Date date = new Date();
    SimpleDateFormat format = new SimpleDateFormat("今天是yyyy-MM-dd E hh:mm:ss,是yyyy年的第DD天,在该月是第dd天");
    System.out.println(format.format(date));
    将会输出:今天是2015-12-10 星期四 09:38:16,是2015年的第344天,在该月是第10

    2.NumberFormat

    NumberFormat根据当前语言环境格式化数字
    NumberFormat同样是一个抽象基类,可以使用API中的工厂方法获取实例对象
    1.getCurrencyInstance()方法,根据当前语言环境获取货币数值格式。传递Locale对象可以获取指定语言环境下的货币数值格式,比如

    NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CANADA);
    System.out.println(format.format(439.6));
    将会输出:$439.60

    2.getInstance()getNumberInstance()方法都会获取到常规数值格式
    3.getIntegerInstance()方法获取常规整数值格式,如果需要格式化的数值为小数,则会将数值四舍五入为最接近的整数
    4.getPercentInstance()方法获取百分比的数值格式
    NumberFormat有两个具体实现子类DecimalFormatChoiceFormat

    DecimalFormat

    DecimalFormat同SimpleDateFormat类似,允许我们指定格式模式获取我们想要的格式化数值
    DecimalFormat类对于数值的小数部分,默认显示3位小数,在去掉超出小数点后面3位的部分时,会将数值四舍五入为最接近的数值格式化输出。淡然我们可以对这个默认进行设置
    setMaximumFractionDigits(int newValue)方法,设置小数部分中允许的最大数字位数
    setMinimumFractionDigits(int newValue)方法,设置小数部分中允许的最小数字位数,如果原数小数位数不够的话,会补零。
    对于数值的整数部分,默认3个数字为一组进行显示,同样对此我们也可以自定义,使用setGroupingSize(int i)方法,设置分组中一组的位数。
    setGroupingUsed(boolean value)方法设置是否使用分组,true表示使用,false表示取消分组
    setMaximumIntegerDigits(int newValue)方法设置整数部分允许的最大数字位数
    setMinimumIntegerDigits(int newValue)方法设置整数部分允许的最小数字位数
    在````的构造方法中,允许我们传入格式模式字符串输出我们想要的格式化数值,格式模式元素包含如下

       
    0 表示一个数字,被格式化数值不够的位数会补0
    # 表示一个数字,被格式化数值不够的位数会忽略
    . 小数点分隔符的占位符
    , 分组分隔符的占位符
    - 缺省负数前缀
    % 将数值乘以100并显示为百分数
    u2030 将数值乘以1000并显示为千分数

    再次


    DecimalFormat format1 = new DecimalFormat("#u2030");
    System.out.println(format1.format(0.3345));//输出334‰
    

    DecimalFormat format2 = new DecimalFormat("##.##");
    System.out.println(format2.format(12.345));//输出12.35

    DecimalFormat format3 = new DecimalFormat("0000.00");
    System.out.println(format3.format(12.345));//输出0012.35

    DecimalFormat format4 = new DecimalFormat("#.##%");
    System.out.println(format4.format(12.345));//输出1234.5%

    ChoiceFormat

    ChoiceFormat允许将格式化运用到某个范围的数,通常与MessageFormat一同使用。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数组中寻找相同索引的值。例子:

    double[] limits = { 3, 4, 5, 6, 7, 8, 9 };
    String[] formats = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
    ChoiceFormat format = new ChoiceFormat(limits, formats);
    System.out.println(format.format(2.5));//将会输出"星期一"
    /**3.6介于3和4之间,所以会匹配3,又由于3在limits数组中的索引是0,所以会在formats数组徐照索引0的值,即输出"星期一"
    */
    System.out.println(format.format(3.6));

    下面看一下ChoiceFormat类中的几个常用方法
    1.nextDouble(double d)静态方法查找大于d的最小double值,用在limits数组中,从而使limits数组形成一个右开区间数组,例如
    limits = {0,1,ChoiceFormat.nextDouble(1)}
    2.nextDouble(double d, boolean positive)静态方法,如果positive参数为true,表示查找大于d的最小double值;如果positive参数为false,表示查找小于d的最大double值,这样就可以使limits形成一个左开区间数组。
    3.previousDouble(double d)静态方法,查找小于d的最大double值
    ChoiceFormat类的构造方法也允许我们传入一个模式字符串,format方法会根据这个模式字符串执行格式化操作。一个模式元素的格式如下:

    doubleNum [占位符] formatStr

    占位符可以使用#、< 、u2264(<=)

    ChoiceFormat cf = new ChoiceFormat("1#is 1 | 1<is more than 1");
    System.out.println(cf.format(1));//输出"is 1"
    System.out.println(cf.format(2));//输出"is more than 1"
    System.out.println(cf.format(0));//输出"is 1"

    由上面的例子可以看出,模式字符串中的每个模式元素之间使用"|"分割,"|"前后可以添加空格以美化代码,而且必须按照升序进行书写,否则会出现java.lang.IllegalArgumentException的运行时异常。
    观看ChoiceFormat类的源码我们得知,实际上在内部,模式字符串还是被转换为limits和formats两个数组。在源码中

    public ChoiceFormat(String newPattern)  {
         applyPattern(newPattern);
    }
    /** applyPattern(newPattern)方法的部分源码
    */
    public void applyPattern(String newPattern) {
    ...
    choiceLimits = new double[count];
    System.arraycopy(newChoiceLimits, 0, choiceLimits, 0, count);
    choiceFormats = new String[count];
    System.arraycopy(newChoiceFormats, 0, choiceFormats, 0, count);
    ...
    }

    可以看出ChoiceFormat(String newPattern)调用了applyPattern(String newPattern)方法,在applyPattern方法中对newPattern字符串进行解析,然后将解析后的数据放置到ChoiceFormat类的两个私有属性double[] choiceLimitsString[] choiceFormats中,然后使用格式化方法即可。

    3.MessageFormat

    MessageFormat提供了以语言环境无关的生成连接消息的方式。
    常用MessageFormat的静态方法format,该方法接收一个字符串的模式和一组对象(对象数组),按照模式形式将格式化的对象插入到模式中,然后返回字符串结果。
    MessageFormat的格式模式元素(FormatElement)形式如下:
    {ArgumentIndex}
    {ArgumentIndex,FormatType}
    {ArgumentIndex,FormatType,FormatStyle}
    其中ArgumentIndex对象数组中的索引,从0开始,
    FormatType包括number、date、 time、choice,
    FormatStyle包括short、medium、long、full、integer、currency、percent、SubformatPattern(子模式),
    在MessageFormat类的内部,FormatType和FormatStyle实际上是创建格式元素的Format示例
    number对应了NumberFormat,其子格式对应了DecimalFormat
    date和time对应了DateFormat,其资格是对应了SimpleDateFormat
    choice对应了ChoiceFormat
    敢说没有意思,来多举几个栗子:
    你可以直接使用MessageFormat类中的静态方法format,像这样:

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

    你也可以使用MessageFormat的构造方法传入pattern string(模式字符串),然后调用普通的format方法,在这里就不举栗子了。
    我们不仅被允许使用MessageFormat类中提供默认的FormatElement去format这些对象,还可以设置自己的Format对象format这些Object。

    /**在这个例子中,MessageFormat和ChoiceFormat被结合使用
    * MessageFormat类中有3个方法值的我们关注
    * 1.setFormatByArgumentIndex(int argumentIndex, Format newFormat)//
    * 2.setFormats(Format[] newFormats)
    * 3.setFormat(int formatElementIndex, Format newFormat)
    * 在这个例子当中,在MessageFormat的模式字符串的FormatElement(即{}中的内容)中
    * 索引为0的地方将使用ChoiceFormat的格式去格式化。
    * 如果在set的Format中仍具有FormatElement,则会递归调用MessageFormat的format方法。
    */
    MessageFormat form = new MessageFormat("The disk "{1}" contains {0}.");
    double[] filelimits = { 0, 1, 2 };
    String[] filepart = { "no files", "one file", "{0,number} files" };
    ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
    form.setFormatByArgumentIndex(0, fileform);
    int fileCount = 1273;
    String diskName = "MyDisk";
    Object[] testArgs = { new Long(fileCount), diskName };
    System.out.println(form.format(testArgs));
    //输出:The disk "MyDisk" contains 1,273 files.

    4.String类中的format方法

    format方法使用占位符进行格式化
    常规类型、字符类型和数值类型的占位符格式:
    %[index$][标识][最小宽度][.精度]转换符
    日期和时间类型的占位符格式:
    %[index$][标识][最小宽度]转换符
    与参数不对应的占位符格式:
    %[标识][最小宽度]转换符
    其中index表示参数列表中的位置上的值
    可用标识:

    标识 含义
    - 在最小宽度内左对齐,不可与0标识一起使用
    0 若内容长度不足最小宽度,则在左边用0来填充
    # 对8进制和16进制,8进制前添加一个0,16进制前添加0x
    + 结果总包含一个+或-号
    空格 正数前加空格,负数前加-号
    , 只用与十进制,每3位数字间用,分隔
    ( 若结果为负数,则用括号括住,且不显示符号

    可用转换符:

    转换符 含义
    b 布尔类型,只要实参为非false的布尔类型,均格式化为字符串true,否则为字符串false
    n 平台独立的换行符, 也可通过System.getProperty("line.separator")获取
    f 浮点数型(十进制)。显示9位有效数字,且会进行四舍五入。如99.99
    a 浮点数型(十六进制)
    e 指数类型。如9.38e+5
    g 浮点数型(比%f,%a长度短些,显示6位有效数字,且会进行四舍五入)
    s 字符串类型
    c 字符类型

    String result1 = String.format("小明今年%d岁,他住在%s,他的月工资有%.2f", 25,"北京市",6633.435);
    System.out.println(result1);//输出:小明今年25岁,他住在北京市,他的月工资有6633.44
    /*****************************************************/
    double num = 123.4567899;
    String result2 = String.format("%e", num);
    System.out.println(result2);//输出:1.234568e+02

    总结

    1.Format中的子类都是不同步,所以需要注意线程安全问题
    2.可能在某些地方我解释的还是不太清楚。学习最重要的是多去尝试,多编写代码测试,如果仅仅靠看就能学会的话,那你就看吧、

    以上是对自己学习的总结,如有错误的地方请提出来,我会

    	<div class="article-bar-bottom">
    					<div class="tags-box artic-tag-box">
    		<span class="label">文章标签:</span>
    					<a class="tag-link" href="http://so.csdn.net/so/search/s.do?q=java&amp;t=blog" target="_blank">java						</a><a class="tag-link" href="http://so.csdn.net/so/search/s.do?q=format&amp;t=blog" target="_blank">format						</a><a class="tag-link" href="http://so.csdn.net/so/search/s.do?q=格式化&amp;t=blog" target="_blank">格式化						</a>
    	</div>
    					<div class="tags-box">
    		<span class="label">个人分类:</span>
    					<a class="tag-link" href="https://blog.csdn.net/joenqc/article/category/6701812" target="_blank">java						</a>
    	</div>
    				</div>
    
    <!-- !empty($pre_next_article[0]) -->
    	</div>
    
        <a id="commentBox"></a>
    
    • 上一页
    • 1
    • 下一页
    </div>
    


    						<script>
    			(function() {
    				var s = "_" + Math.random().toString(36).slice(2);
    				document.write('<div id="' + s + '"></div>');
    				(window.slotbydup=window.slotbydup || []).push({
    					id: '4765209',
    					container: s,
    					size: '808,120',
    					display: 'inlay-fix'
    				});
    			})();
    			</script><div id="_trfi11f6jj"></div><script charset="utf-8" src="https://pos.baidu.com/scsm?di=4765209&amp;dri=0&amp;dis=0&amp;dai=0&amp;ps=9876x367&amp;enu=encoding&amp;dcb=___adblockplus&amp;dtm=SSP_JSONP&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1526536356746&amp;ti=Java%E4%B8%AD%E5%BC%BA%E5%A4%A7%E7%9A%84format%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;dbv=2&amp;drs=1&amp;pcs=1903x925&amp;pss=1903x9933&amp;cfv=0&amp;cpl=4&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1526536356&amp;prot=2&amp;rw=925&amp;ltu=https%3A%2F%2Fblog.csdn.net%2Fjoenqc%2Farticle%2Fdetails%2F56014679&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DlZlMb4Q-MHsVuRgkfPJn8lFYBWiyjRXGr6at4dq08wsig9U5lAOVduYH5izUIk-q0oMJxKsRzD7uShFgIySJya%26wd%3D%26eqid%3D82db6d1500036733000000035afd0e4e&amp;lcr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DlZlMb4Q-MHsVuRgkfPJn8lFYBWiyjRXGr6at4dq08wsig9U5lAOVduYH5izUIk-q0oMJxKsRzD7uShFgIySJya%26wd%3D%26eqid%3D82db6d1500036733000000035afd0e4e&amp;ecd=1&amp;uc=1920x1040&amp;pis=-1x-1&amp;sr=1920x1080&amp;tcn=1526536357"></script><iframe scrolling="no" style=" 100%; height: 90px; border: 0px;"></iframe>
    
    广告
    			<script src="http://dup.baidustatic.com/js/os.js"></script>
    
    		
    	</div>
    			<div class="recommend-item-box csdn-tracking-statistics" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
    	<h4 class="text-truncate">
    		<a href="https://blog.csdn.net/lonely_fireworks/article/details/7962171" target="_blank" strategy="BlogCommendFromBaidu_2">
    			<em>JAVA</em>字符串格式化-String.<em>format</em>()的使用			</a>
    	</h4>
    	<p class="content">
    		<a href="https://blog.csdn.net/lonely_fireworks/article/details/7962171" target="_blank">
    			常规类型的格式化
    

    String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处。format()方法有两种...





    lonely_fireworks
    lonely_fireworks



    2012-09-10 11:01:10



    阅读数:729631













    海参市场乱象丛生 购买时要擦亮双眼
    富果 · 顶新










    A+B Format (20)的JAVA实现




    PAT





    liuestcjun
    liuestcjun



    2017-03-27 17:41:10



    阅读数:357













    Java 格式化类(java.util.Formatter)基本用法




    转自:
    http://www.blogjava.net/AS-COM/archive/2011/03/15/346321.html?opt=admin

    有时会想把数字,日期,字符串按照...





    zxm1306192988
    zxm1306192988



    2016-10-13 19:25:45



    阅读数:5411











    没有更多推荐了,返回首页




  • 相关阅读:
    numpy用法介绍-未完待续
    GeoJSON相关操作
    awk日志分析
    awk获取外部变量
    Shell编程二
    Shell编程
    Linux监控平台搭建
    Linux集群架构
    Linux集群
    MySQL主从(MySQL proxy Lua读写分离设置,一主多从同步配置,分库分表方案)
  • 原文地址:https://www.cnblogs.com/jobs-lgy/p/9050727.html
Copyright © 2011-2022 走看看