字符串格式化汇总
Table of Contents
- 1. ++
- 2. StringBuffer / StringBuilder
- 3. StringUtil.format(String, Object…)
- 4. MessageFormatUtil.format(String, Object…)
- 5. Slf4jUtil.format(String, Object…)
- 6. StringUtil.replace(CharSequence, Map<String, V>)
- 7. VelocityUtil.parseString(String, Map<String, ?>)
- 8. VelocityUtil.parseTemplateWithClasspathResourceLoader(String, Map<String, ?>)
- 9. 性能对比
在开发过程中,经常会和字符串打交道, 其中字符串拼接的工作必不可少,
比如:
我要生成一个如此格式的路径,有什么办法?
String path= "/home/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery_${fileName}.log";
其中的:
我们来汇总下实现方式
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
<dependency> <groupId>com.feilong.platform.tools</groupId> <artifactId>feilong-tools-velocity</artifactId> <version>${version.feilong-platform}</version> </dependency>
@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
<dependency> <groupId>com.feilong.platform.tools</groupId> <artifactId>feilong-tools-velocity</artifactId> <version>${version.feilong-platform}</version> </dependency>
该方法适合于 字符串模板独立成文件, 方便维护
路径是classpath 下面, 比如 velocity/path.vm
此时代码需要如此调用:
@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. 性能对比
上图是 分别循环 100000, 500000, 1000000, 2000000 统计出来的数据
在性能上 String format 是最差的
字符串 ++ 最快, StringBuilder 次之 , slf4j 的格式化再次之
测试硬件概览:
型号名称: MacBook Pro 处理器名称: Intel Core i5 处理器速度: 2.9 GHz 内存: 16 GB