Java字符串模板格式化汇总8法(附性能对比)

Wesley13
• 阅读 473

Table of Contents

在开发过程中,经常会和字符串打交道, 其中字符串拼接的工作必不可少,

比如:

我要生成一个如此格式的路径,有什么办法?

String path= "/home/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery_${fileName}.log";

其中的:

yearMonth

是当前日期的年月

expressDeliveryType

是物流方式的类型,以顺丰sf举例 ,如果是其他快递会是其他值

fileName

是当前时间的时间戳

我们来汇总下实现方式

1. ++

对于初学JAVA的蒙童,大约都会使用这招

@Test public void testAdd(){

Date now = new Date();

String yearMonth = DateUtil.toString(now, DatePattern.YEAR\_AND\_MONTH);
String expressDeliveryType = "sf";
String fileName = DateUtil.toString(now, DatePattern.TIMESTAMP);

String template = "/home/expressdelivery/" + yearMonth + "/" + expressDeliveryType + "/vipQuery\_" + fileName + ".log";

System.out.println(template);

}

输出 :

/home/expressdelivery/2017-07/sf/vipQuery_20170723042314.log

2. StringBuffer / StringBuilder

@Test public void testStringBuilder(){

Date now = new Date();

String yearMonth = DateUtil.toString(now, DatePattern.YEAR\_AND\_MONTH);
String expressDeliveryType = "sf";
String fileName = DateUtil.toString(now, DatePattern.TIMESTAMP);

StringBuilder sb = new StringBuilder();
sb.append("/home/expressdelivery/");
sb.append(yearMonth);
sb.append("/");
sb.append(expressDeliveryType);
sb.append("/vipQuery\_");
sb.append(fileName);
sb.append(".log");

String template = sb.toString();

System.out.println(template);

}

输出 :

/home/expressdelivery/2017-07/sf/vipQuery_20170723042603.log

缺点:

  • 代码太长了

3. StringUtil.format(String, Object…​)

使用 com.feilong.core.lang.StringUtil.format(String, Object…​)

内部封装了 String.format(String, Object)

@Test public void testStringFormat(){ Date now = new Date();

String yearMonth = DateUtil.toString(now, DatePattern.YEAR\_AND\_MONTH);
String expressDeliveryType = "sf";
String fileName = DateUtil.toString(now, DatePattern.TIMESTAMP);

String template = StringUtil.format("/home/expressdelivery/%s/%s/vipQuery\_%s.log", yearMonth, expressDeliveryType, fileName);

System.out.println(template);

}

输出 :

/home/expressdelivery/2017-07/sf/vipQuery_20170723043153.log

4. MessageFormatUtil.format(String, Object…​)

使用 com.feilong.core.text.MessageFormatUtil.format(String, Object…​)

内部封装了 java.text.MessageFormat.format(String, Object…​)

@Test public void testMessageFormat(){ Date now = new Date();

String yearMonth = DateUtil.toString(now, DatePattern.YEAR\_AND\_MONTH);
String expressDeliveryType = "sf";
String fileName = DateUtil.toString(now, DatePattern.TIMESTAMP);

String template = MessageFormatUtil
                .format("/home/expressdelivery/{0}/{1}/vipQuery\_{2}.log", yearMonth, expressDeliveryType, fileName);

System.out.println(template);

}

输出 :

/home/expressdelivery/2017-07/sf/vipQuery_20170723043153.log

5. Slf4jUtil.format(String, Object…​)

使用 com.feilong.tools.slf4j.Slf4jUtil.format(String, Object…​)

借助 slf4j 日志占位符

@Test public void testSlf4jFormat(){ Date now = new Date();

String yearMonth = DateUtil.toString(now, DatePattern.YEAR\_AND\_MONTH);
String expressDeliveryType = "sf";
String fileName = DateUtil.toString(now, DatePattern.TIMESTAMP);

String template = Slf4jUtil.format("/home/expressdelivery/{}/{}/vipQuery\_{}.log", yearMonth, expressDeliveryType, fileName);

System.out.println(template);

}

输出:

/home/expressdelivery/2017-07/sf/vipQuery_20170723144236.log

6. StringUtil.replace(CharSequence, Map<String, V>)

使用 com.feilong.core.lang.StringUtil.replace(CharSequence, Map<String, V>)

内部封装了 apache commons-lang3 org.apache.commons.lang3.text.StrSubstitutor , 现在叫 commons-text

使用给定的字符串 templateString 作为模板,解析匹配的变量 .

@Test public void testReplace(){ Date date = new Date(); Map<String, String> map = new HashMap<>(); map.put("yearMonth", DateUtil.toString(date, YEAR_AND_MONTH)); map.put("expressDeliveryType", "sf"); map.put("fileName", DateUtil.toString(date, TIMESTAMP));

String template = StringUtil.replace("/home/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery\_${fileName}.log", map);

System.out.println(template);

}

输出:

/home/expressdelivery/2017-07/sf/vipQuery_20170723144608.log

优点:

  • 模块可以定义变量名字了,不怕混乱

Note

此方法只能替换字符串,而不能像el表达式一样使用对象属性之类的来替换

7. VelocityUtil.parseString(String, Map<String, ?>)

使用 com.feilong.tools.velocity.VelocityUtil.parseString(String, Map<String, ?>)

该方法需要 jar

com.feilong.platform.tools feilong-tools-velocity ${version.feilong-platform}

@Test public void testVelocityParseString(){ Date date = new Date();

Map<String, String> map = new HashMap<>();
map.put("yearMonth", DateUtil.toString(date, YEAR\_AND\_MONTH));
map.put("expressDeliveryType", "sf");
map.put("fileName", DateUtil.toString(date, TIMESTAMP));

VelocityUtil velocityUtil = new VelocityUtil();

String template = velocityUtil
                .parseString("/home/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery\_${fileName}.log", map);

System.out.println(template);

}

输出

/home/expressdelivery/2017-07/sf/vipQuery_20170723145856.log

8. VelocityUtil.parseTemplateWithClasspathResourceLoader(String, Map<String, ?>)

使用 com.feilong.tools.velocity.VelocityUtil.parseTemplateWithClasspathResourceLoader(String, Map<String, ?>)

该方法需要 jar

com.feilong.platform.tools feilong-tools-velocity ${version.feilong-platform}

该方法适合于 字符串模板独立成文件, 方便维护

路径是classpath 下面, 比如 velocity/path.vm

Java字符串模板格式化汇总8法(附性能对比)

此时代码需要如此调用:

@Test public void testVelocityParseTemplateWithClasspathResourceLoader(){ Date date = new Date();

Map<String, String> map = new HashMap<>();
map.put("yearMonth", DateUtil.toString(date, YEAR\_AND\_MONTH));
map.put("expressDeliveryType", "sf");
map.put("fileName", DateUtil.toString(date, TIMESTAMP));

VelocityUtil velocityUtil = new VelocityUtil();

String template = velocityUtil.parseTemplateWithClasspathResourceLoader("velocity/path.vm", map);

System.out.println(template);

}

输出 :

/home/expressdelivery/2017-07/sf/vipQuery_20170723150443.log

9. 性能对比

Java字符串模板格式化汇总8法(附性能对比)

上图是 分别循环 100000, 500000, 1000000, 2000000 统计出来的数据

在性能上 String format 是最差的

字符串 ++ 最快, StringBuilder 次之 , slf4j 的格式化再次之

测试硬件概览:

型号名称:    MacBook Pro
处理器名称:    Intel Core i5
处理器速度:    2.9 GHz
内存:    16 GB

10. 参考

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
P2P技术揭秘.P2P网络技术原理与典型系统开发
Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这