Java中的printf

转载:https://blog.csdn.net/KingBoyWorld/article/details/69951340###;

1.简单分析

System.out.printf(String format, Object ... args);
  
  
  • 1
  1. 首先通过System拿到静态对象public final static PrintStream out = null;,类型为PrintStream。

  2. 调用PrintStream的public PrintStream printf(String format, Object ... args)方法。

  3. printf方法内部调用了public PrintStream format(String format, Object ... args)方法。看看format方法的内部实现。

public PrintStream format(String format, Object ... args) {
        try {
            synchronized (this) {
                ensureOpen();
                if ((formatter == null)
                    || (formatter.locale() != Locale.getDefault()))
                    formatter = new Formatter((Appendable) this);
                formatter.format(Locale.getDefault(), format, args);
            }
        } catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        } catch (IOException x) {
            trouble = true;
        }
        return this;
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 可以看出是通过Formatter类的format(Locale l, String format, Object … args)方法进行格式化的;

2.Formatter类介绍与使用

Formatter体系

public final class Formatter
    extends Object
    implements Closeable, Flushable
  
  
  • 1
  • 2
  • 3

printf风格格式的字符串解释器。Formatter可以格式化数字,字符串和日期/时间数据等,将其以特定格式输出。通过Formattable接口提供了用于任意用户类型的限制格式化定制。
对于多线程访问,格式化器不一定是安全的。线程安全是可选的,是本课程中用户的责任。

Java语言的格式化打印受C的printf的极大启发。尽管格式字符串类似于C,但是已经进行了一些自定义以适应Java语言并利用其一些功能。此外,Java格式化比C更严格;例如,如果转换与标志不兼容,将抛出异常。在C中,不适用的标志被忽略。因此,格式字符串旨在被C程序员识别,但不一定完全与C中的那些完全兼容。

//Examples for expected usage:
//先看一个简单的使用示例:
   @Test
    public void formatter_test(){
        StringBuilder sb = new StringBuilder();
        // Send all output to the Appendable object sb
        //用StringBuilder构建一个Formatter,将输出传入到StringBuilder
        Formatter formatter = new Formatter(sb, Locale.CHINA);


        // Explicit argument indices may be used to re-order output.
        //是可以重新排序的,4$即代表第四个参数
        formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
        // -> " d  c  b  a"

        // Optional locale as the first argument can be used to get
        // locale-specific formatting of numbers.  The precision and width can be
        // given to round and align the value.
        //locale参数可以用来获取指定环境下的格式。
        formatter.format(Locale.FRANCE, "\ne = %+10.4f", Math.E);
        // -> "e =    +2,7183"

        // The '(' numeric flag may be used to format negative numbers with
        // parentheses rather than a minus sign.  Group separators are
        // automatically inserted.
        //( 左括号是用来格式化负数的。如果是正数,这个括号不会输出
        formatter.format("\nAmount gained or lost since last statement:  %(,.2f",
                -1.7890);

        System.out.println(sb);
        //        d  c  b  a
        //        e =    +2,7183
        //        Amount gained or lost since last statement:  (12,345.79)
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

再来看一个时间的格式化示例:

    @Test
    public void calendar_test(){
        Calendar c = Calendar.getInstance();
        String s = String.format("Today :%1$tm</span> <span class="hljs-variable">%1te</span>,<span class="hljs-variable">%1</span><span class="hljs-variable">$tY",c);
        System.out.println(s);
        //output:Today :04 10,2017
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

"Today :%1$tm %1te,%1$tY"串是format方法的第一个参数。它包含三个格式说明符“%1表示第几个变量,tm te tY是取日期的flag。格式字符串的其余部分是固定文本。参数列表由传递给格式字符串后的方法的所有参数组成。在上面的例子中,参数列表大小为1,由Calendar对象c组成。

标准的格式写法:

 %[argument_index$][flags][width][.precision]conversion
  
  
  • 1
  • argument_index是一个十进制整数,表示参数在参数列表中的位置。 第一个参数为“1&#x201D;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x4E3A;&#x201C;2” role=”presentation”>2”,第二个为“2”等。
  • flags是修改输出格式的一组字符。
  • width是一个正十进制整数,表示要写入输出的最小字符数。
  • precision通常用于限制字符数的非负十进制整数。

**对于日期和时间的格式是特殊的

%[argument_index$][flags][width]conversion
  
  
  • 1
  • 转换表达式是两个字符。 第一个字符是’t’或’T’。 第二个字符表示要使用的格式,如示例中的meY等

3.具体介绍下参数的用法:

常用操作符

使用b输出false ,大写b则输出FALSE,大写方式相当于转换大写

符号分类描述示例
b,B通用传入的参数有值就打印true,为null返回falseSystem.out.printf("%1$b",null);//false</code> <br><code>System.out.printf("%1$b","hello");//true
h,H通用如果为null,打印null,否则返回hashCode的16进制System.out.printf("%1$h","hell");//30cf3d</code> <br><code>System.out.printf("%1$h",null);//null
s,S通用如果为null,打印null,否则返回arg.toStringsystem.out.printf("%1$s","hell");//hell
dintegral返回十进制数System.out.printf(“%1$d",0100);//八进制-64</code> <br> System.out.printf(“%1$d”,0x100);//十六进制-256
ointegral返回八进制
x,Xintegral返回十六进制
ffloating格式化floatSystem.out.printf("%1$.2f",100.1234555);//100.12</code>,.2表示保留几个小数,默认保留5个。<br><code>System.out.printf("%1$5.2f",1.1);// 1.10,5表示至少显示五个字符,1.1不满5个字符,则输出" 1.10",加上小数点正好五个。
t,Tdate/time时间格式后面单独介绍
%percent返回%号System.out.printf("%f%%", 1.0/3);

输出0.333333%。 |
|n|line Separator|换行|System.out.printf(“hello%ninfo”);
hello
info|

时间日期类

(不要忘了加t/T,例如:System.out.printf("%1$tH",new Date());)

Date/Time
converdes
H24 小时,i.e 00 - 23
I12 小时,i.e 01 - 12
k24 小时,i.e 0 - 23
l12 小时,i.e 1 - 12
M分钟 i.e 00 - 59
S秒 i.e 00 - 60
L毫秒 i.e 000 - 999
N纳秒 i.e 000000000 - 999999999
p上午下午 i.e am pm
sunix时间戳,从1970 00:00:00开始 范围:Long.Min_VALUE/1000 - Long.MAX_VALUE/1000;
Q毫秒 从1970 00:00开始,范围:Long.MIN_VALUE - Long.MAX_VALUE;
Date
converdes
B月份全英文名.
”January”, “February”.
b月份英文缩写,
e.g. “Jan”, “Feb”.
hSame as ‘b’.
A星期的英文全名,
e.g. “Sunday”, “Monday”
a星期的英文缩写,
e.g. “Sun”, “Mon”
‘C’年份/100,如2017年则为20,
i.e. 00 - 99
‘Y’四位的年份,
e.g. 2017
‘y’两位的年份,
e.g. 17 i.e. 00 - 99.
‘j’一年中的第几天,
e.g. 001 - 366

m |第几个月,
i.e. 01 - 13.(官方文档写的13)|
|d| 一月中的第几天,
i.e. 01 - 31|
|e |一月中的第几天,
i.e. 1 - 31.|

有一些格式化好的格式可以直接用
converdes
R格式化为 24-hour,
相当于 “%tH:%tM” ,
e.g. 16:16
T格式化为 24-hour,
相当于 “%tH:%tM:%tS” ,
e.g. 16:16:29
r格式化为 12-hour ,
相当于 “%tI:%tM:%tS %Tp”,
e.g 04:16:06 下午
D相当于 “%tm/%td/%ty,
e.g. 04/10/17”.
F相当于 “%tY-%tm-%td”,
e.g. 2017-04-10
c相当于 “%ta %tb %td %tT %tZ %tY”,
e.g. “Sun Jul 20 16:17:00 EDT 1969”.

Flag

FlagGeneralCharacterIntegralFloating PointDate/TimeDescription
‘-‘yyyyy结果会左对齐
‘#’y-yy-输出带有标志位的数,
例如System.out.printf("%1$#x",100);//0x64
‘+’--yy-输出带符号的数
‘0’--yy-没有的用0占位,
System.out.printf("%1$06.2f",1.12345);//001.12
‘,’--yy-将数字用逗号隔开,更方便看System.out.printf("%1$,.2f",12345.12345);//12,345.12
‘(‘--yy-如果结果是负数,会用括号括起来,正数没有括号
System.out.printf("%1$(,.2f",-12345.12345);
(12,345.12)

日期的示例

// %t表示格式化日期时间类型,%T是时间日期的大写形式,在%t之后用特定的字母表示不同的输出格式
Date date = new Date();
long dataL = date.getTime();
// 格式化年月日
// %t之后用y表示输出日期的年份(2位数的年,如99)
// %t之后用m表示输出日期的月份,%t之后用d表示输出日期的日号
System.out.printf("%1$ty-%1$tm-%1$td; %2$ty-%2$tm-%2$td%n", date, dataL);
// %t之后用Y表示输出日期的年份(4位数的年),
// %t之后用B表示输出日期的月份的完整名, %t之后用b表示输出日期的月份的简称
System.out.printf("%1$tY-%1$tB-%1$td; %2$tY-%2$tb-%2$td%n", date, dataL);

// 以下是常见的日期组合
// %t之后用D表示以 "%tm/%td/%ty"格式化日期
System.out.printf("%1$tD%n", date);
//%t之后用F表示以"%tY-%tm-%td"格式化日期
System.out.printf("%1$tF%n", date);

/*** 输出时间类型***/
// 输出时分秒
// %t之后用H表示输出时间的时(24进制),%t之后用I表示输出时间的时(12进制),
// %t之后用M表示输出时间的分,%t之后用S表示输出时间的秒
System.out.printf("%1$tH:%1$tM:%1$tS; %2$tI:%2$tM:%2$tS%n", date, dataL);
// %t之后用L表示输出时间的秒中的毫秒
System.out.printf("%1$tH:%1$tM:%1$tS %1$tL%n", date);
// %t之后p表示输出时间的上午或下午信息
System.out.printf("%1$tH:%1$tM:%1$tS %1$tL %1$tp%n", date);
// 以下是常见的时间组合
// %t之后用R表示以"%tH:%tM"格式化时间
System.out.printf("%1$tR%n", date);
// %t之后用T表示以"%tH:%tM:%tS"格式化时间
System.out.printf("%1$tT%n", date);
// %t之后用r表示以"%tI:%tM:%tS %Tp"格式化时间
System.out.printf("%1$tr%n", date);

/*** 输出星期***/
// %t之后用A表示得到星期几的全称
System.out.printf("%1$tF %1$tA%n", date);
// %t之后用a表示得到星期几的简称
System.out.printf("%1$tF %1$ta%n", date);

// 输出时间日期的完整信息
System.out.printf("%1$tc%n", date);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

数字的示例

double d = 345.678; 

String s = ‘你好!’; 

int i = 1234;         //’%’表示进行格式化输出,’%’之后的内容为格式的定义。        

System.out.printf(‘%f’,d); //’f’表示格式化输出浮点数。        

System.out.println(); 

System.out.printf(‘%9.2f’,d); //’9.2’中的9表示输出的长度,2表示小数点后的位数。        

System.out.println(); 

System.out.printf(‘%+9.2f’,d); //’+’表示输出的数带正负号。        

System.out.println(); 

System.out.printf(‘%-9.4f’,d); //’-‘表示输出的数左对齐(默认为右对齐)。        

System.out.println(); 

System.out.printf(‘%+-9.3f’,d); //’+-‘表示输出的数带正负号且左对齐。    

System.out.println(); 

System.out.printf(‘%d’,i); //’d’表示输出十进制整数。        

System.out.println(); 

System.out.printf(‘%o’,i); //’o’表示输出八进制整数。        

System.out.println(); 

System.out.printf(‘%x’,i); //’d’表示输出十六进制整数。        

System.out.println(); 

System.out.printf(‘%#x’,i); //’d’表示输出带有十六进制标志的整数。       

System.out.println(); 

System.out.printf(‘%s’,s); //’d’表示输出字符串。        

System.out.println(); 

System.out.printf(‘输出一个浮点数:%f,一个整数:%d,一个字符串:%s’,d,i,s);        //可以输出多个变量,注意顺序。        

System.out.println(); 

System.out.printf(’ 字符串:%2$s,%1$d的十六进制数:%1$#x'</span>,i,s);      <span class="hljs-comment">//'X$’表示第几个变量。       } 浮点数。           

System.out.println(); 

System.out.printf(‘%9.2f’,d);//’9.2’中的9表示输出的长度,2表示小数点后的位数。          

System.out.println(); 

System.out.printf(‘%+9.2f’,d); //’+’表示输出的数带正负号。          

System.out.println(); 

System.out.printf(‘%-9.4f’,d);//’-‘表示输出的数左对齐(默认为右对齐)。 

System.out.println(); 

System.out.printf(‘%+-9.3f’,d); //’+-‘表示输出的数带正负号且左对齐。    

System.out.println(); 

System.out.printf(‘%d’,i); //’d’表示输出十进制整数。          

System.out.println(); 

System.out.printf(‘%o’,i); //’o’表示输出八进制整数。          

System.out.println(); 

System.out.printf(‘%x’,i); //’d’表示输出十六进制整数。          

System.out.println(); 

System.out.printf(‘%#x’,i); //’d’表示输出带有十六进制标志的整数。         System.out.println();           System.out.printf(‘%s’,s); //’d’表示输出字符串。         System.out.println();           System.out.printf(‘输出一个浮点数:%f,一个整数:%d,一个字符串:%s’,d,i,s);          //可以输出多个变量,注意顺序。          

System.out.println(); 

System.out.printf(’ 字符串:%2$s,%1$d的十六进制数:%1$#x'</span>,i,s);          <span class="hljs-comment">//'X$’表示第几个变量。         }          }           

//定义一些变量,用来格式化输出。
double d = 345.678;
String s = “你好!”;
int i = 1234; //”%”表示进行格式化输出,”%”之后的内容为格式的定义。
System.out.printf(“%f”,d);//”f”表示格式化输出浮点数。
System.out.println();
System.out.printf(“%9.2f”,d);//”9.2” 中的9表示输出的长度,2表示小数点后的位数。 System.out.println();
System.out.printf(“%+9.2f”,d);//”+” 表示输出的数带正负号。
System.out.println();
System.out.printf(“%-9.4f”,d);//”-” 表示输出的数左对齐(默认为右对齐)。
System.out.println();
System.out.printf(“%+-9.3f”,d);//”+-” 表示输出的数带正负号且左对齐。
System.out.println();
System.out.printf(“%d”,i);//”d”表示输出十进制整数。
System.out.println();
System.out.printf(“%o”,i);//”o”表示输出八进制整数。
System.out.println();
System.out.printf(“%x”,i);//”d”表示输出十六进制整数。
System.out.println();
System.out.printf(“%#x”,i);//”d” 表示输出带有十六进制标志的整数。
System.out.println();
System.out.printf(“%s”,s);//”d”表示输出字符串。
System.out.println();
System.out.printf(“输出一个浮点数:%f,一个整数:%d,一个字符串:%s”,d,i,s); //可以输出多个变量,注意顺序。
System.out.println();
System.out.printf(“字符串:%2 s s , [Math Processing Error]d的十六进制数:%1#x"</span>,i,s);          <span class="hljs-comment">//"X #x"</span>,i,s);          <span class="hljs-comment">//"X ”表示第几个变量。 } }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值