字符串格式化String.format()

220 阅读5分钟

聊聊String.format()方法

前言

String类是我们在java开发中经常会使用到的引用类,它里面提供了很多很实用的方法,比如String.format(),我们常常利用该方法做格式化的输出,本篇文章将主要对String.format()方法的使用进行讲解。

以前我们是怎么输出字符串的

先说说使用String.format方法来输出字符串的优势,我们可以回想一下我们刚开始学习Java时,对于不确定具体内容的参数,往往是使用字符串拼接的方式来进行输出的,比如说像下面这种:

 @Test
    public void print(){
        normalPrint("小明",15,88.88);
    }

    public void normalPrint(String name,int age,double money){
        System.out.println(name + "今年" +age +"岁了,收到了"+money+"块零花钱");
    }

输出结果

我们可以看到,使用上面这种方式我们确实可以完成打印的需求,但是字符串拼接过程中其实是创建了一些我们不需要用到的字符串对象的。所以,面对这种不确定参数内容的场景,String类提供format的格式化方法来帮助我们解决这个问题。

String.format方法的使用

format方法的核心在于对占位符的使用,我们可以预先定义好一个字符串的模板,有了模板之后我们只需要提供参数就行,底层会帮助我们把参数替换到对应的占位符中。我们以上面的案例为例,做一个小优化:
定义的模板字符串为:%s今年%d岁了,收到了%f块零花钱,其中第一个%s表示会将传入的第一个字符串参数替换掉%s这个占位符,对于%d%f也是一样,分别表示整数类型和浮点类型的占位符。

@Test
    public void print(){
        normalPrint("小明",15,88.88);
    }

    public void normalPrint(String name,int age,double money){
        System.out.println(String.format("%s今年%d岁了,收到了%f块零花钱",name,age,money));
    }

从输出结果看,我们可以发现和之前使用字符串拼接的效果一模一样,但是使用format方法却有更多的好处:
(1)参数更加明确,我们可以更加方便的找到输出的元素(在多参数的输出上会体现的更加明显)
(2)降低了产生的无用内存对象

常用的占位符

下面我们将对format方法中常用的占位符进行介绍:

其中我们用的比较多的,一般是字符串、整数、浮点、日期相关的占位符多一些。

转换(占位)符详细说明示例
%s字符串类型“喜欢请收藏”
%c字符类型‘m’
%b布尔类型true
%d整数类型(十进制)88
%x整数类型(十六进制)FF
%o整数类型(八进制)77
%f浮点类型8.888
%a十六进制浮点类型FF.35AE
%e指数类型9.38e+5
%n换行符
%tx日期与时间类型(x代表不同的日期与时间转换符)

我们以上面的占位符为例做一个小例子:

@Test
public void formatTest(){
        String formatPattern = "%tF %s开张了,收益为%f元 %n 顾客满意度为 %s";
        System.out.println(String.format(formatPattern, LocalDateTime.now(),"钱大妈",666.66,"一般"));
    }

输出结果

特殊符号的占位符

标志说明说明结果
+为正数或者负数添加符号,因为 一般整数不会主动加符号(“%+d”,15)+15
0数字前面补0,用于对齐(“%04d”, 99)0099
数字在整数之前添加指定数量的空格(“%4d”, 99)99
,以“,”对数字分组(常用显示金额)(“%,f”, 9999.99)9,999.990000
(使用括号包含负数(“%(f”, -99.99)(99.990000)

我们使用这些特殊的占位符来做一个小测试:

@Test
    public void specialFormatTest(){
        // %+ 可以显示数字的正负符号
        System.out.println(String.format("the number is %+d",19));
        // %04d , 表示该整数最少占4位,不够4位的在前面用0充当占位符
        // 这个属性常常利用做格式化的对齐
        System.out.println(String.format("the number is %04d",19));
        // %,  对于数字进行分割(每3个整数位数字分割一次)
        System.out.println(String.format("the number is %,d",99999999));
        // %(  表示将使用括号来对"负数"进行包裹,比如 -88会被转换输出为 (88)
        System.out.println(String.format("the number is %(d",-888888));
    }

输出结果

日期占位符

我们在常用占位符的介绍中提到了可以通过%tx的方式来定义日期占位符,其中x就需要我们再根据需要填入对应的日期格式。

标志说明示例
c包括全部日期和时间信息周四 10月 21 14:52:10 GMT+08:00 2021
F“年-月-日”格式2021-10-21
D“月/日/年”格式10/21/21
r“HH:MM:SS PM”格式(12时制) 02:53:20 下午
T“HH:MM:SS”格式(24时制)14:53:39
R“HH:MM” 格式(24时制)14:53
b月份本地化10月
y两位的年21
Y四位的年2021
m10
d21
H24小时制的时14
l12小时制的时2
M57
S46
s秒为单位的时间戳1634799527
p上午还是下午下午

同样的,我们根据上面提供的日期占位符来做一个简单的例子:
我们可以看到,我们定义的模板字符串为:today is %1$tY-%1$tm-%1$td,理论上我们需要填入三个参数,但实际上我们只提供了1个日期类,原因是当1个参数会在模板字符串中多次使用时,我们可以使用数字$的方式来对指定位置的参数进行替换。比如说1$表示的就是这里将使用第1个参数进行替换。
同时,还需要注意,我们的索引占位符数字$是需要写在%之后的,否则会识别错误。

@Test
    public void formatTest(){
        System.out.println(String.format("today is %1$tY-%1$tm-%1$td",new Date()));
    }

输出结果