字符串格式化汇总
- 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. 性能对比
- 10. 参考
在开发过程中,经常会和字符串打交道, 其中字符串拼接的工作必不可少,
比如:
我要生成一个如此格式的路径,有什么办法?
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
<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
10. 参考
-
commons-lang3 官方地址: http://commons.apache.org/proper/commons-lang/download_lang.cgi