美文网首页JVM · Java虚拟机原理 · JVM上语言·框架· 生态系统
Java字符串模板格式化汇总8法(附性能对比)

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

作者: java高级架构F六 | 来源:发表于2019-12-13 22:44 被阅读0次

    字符串格式化汇总

    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 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 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

    此时代码需要如此调用:

    @Test

    public void testVelocityParseTemplateWithClasspathResourceLoader(){

    Date date = new Date();

    Map 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

    原文地址:https://www.iteye.com/blog/feitianbenyue-2386699

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/mbbqnctx.html