• String.format字符串拼接


    一、String.Format
    1、简介
          String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。

    2、参数
          format()方法有两种重载形式。

          format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。

          format(Locale locale, String format, Object… args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。

    3、用法


    4、实例
    //测试
    public static void main(String[] args) {
    String str=null;
    str=String.format("Hi,%s", "王力");
    System.out.println(str);
    str=String.format("Hi,%s:%s.%s", "王南","王力","王张");
    System.out.println(str);
    System.out.printf("字母a的大写是:%c %n", 'A');
    System.out.printf("3>7的结果是:%b %n", 3>7);
    System.out.printf("100的一半是:%d %n", 100/2);
    System.out.printf("100的16进制数是:%x %n", 100);
    System.out.printf("100的8进制数是:%o %n", 100);
    System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);
    System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);
    System.out.printf("上面价格的指数表示:%e %n", 50*0.85);
    System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);
    System.out.printf("上面的折扣是%d%% %n", 85);
    System.out.printf("字母A的散列码是:%h %n", 'A');
    }

    //结果
    Hi,王力
    Hi,王南:王力.王张
    字母a的大写是:A
    3>7的结果是:false
    100的一半是:50
    100的16进制数是:64
    100的8进制数是:144
    50元的书打8.5折扣是:42.500000 元
    上面价格的16进制数是:0x1.54p5
    上面价格的指数表示:4.250000e+01
    上面价格的指数和浮点数结果的长度较短的是:42.5000
    上面的折扣是85%
    字母A的散列码是:41
    二、比较
    1、实例说明
    package com.jiedaibao.pay.account.accounting.p.general;


    import junit.framework.TestCase;
    import java.util.ArrayList;
    import java.util.List;
    import org.apache.commons.lang.StringUtils;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;


    /**
    * Unit test for simple App.
    */
    public class AppTest extends TestCase {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void testPlus() {
    String s = "";
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
    s = s + String.valueOf(i);
    }
    long te = System.currentTimeMillis();
    logger.info("+ cost {} ms", te - ts);
    }

    public void testConcat() {
    String s = "";
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
    s = s.concat(String.valueOf(i));
    }
    long te = System.currentTimeMillis();
    logger.info("concat cost {} ms", te - ts);
    }

    public void testJoin() {
    List<String> list = new ArrayList<String>();
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
    list.add(String.valueOf(i));
    }
    StringUtils.join(list, "");
    long te = System.currentTimeMillis();
    logger.info("StringUtils.join cost {} ms", te - ts);
    }

    public void testStringBuffer() {
    StringBuffer sb = new StringBuffer();
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
    sb.append(String.valueOf(i));
    }
    sb.toString();
    long te = System.currentTimeMillis();
    logger.info("StringBuffer cost {} ms", te - ts);
    }

    public void testStringBuilder() {
    StringBuilder sb = new StringBuilder();
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
    sb.append(String.valueOf(i));
    }
    sb.toString();
    long te = System.currentTimeMillis();
    logger.info("StringBuilder cost {} ms", te - ts);
    }

    public void testStringFormat() {
    String str="";
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {

    str=String.format("%s%s",str,String.valueOf(i));

    }
    str.toString();
    long te = System.currentTimeMillis();
    logger.info("StringBuilder cost {} ms", te - ts);
    }
    }

    耗时显示


    特别注意:

          StringBuilder 循环的次数是其它的10倍,如果是一样,那么返回 0,可见StringBuilder 的速度之快。

    2、原理
          为什么String.Format耗时这么厉害呢,我们来看看源码

    StringBuilder的源码
    public AbstractStringBuilder append(String str) {
    if (str == null)
    return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
          其中value是一个char[]类型,我们可以大概了解到实现字符串拼接的原理是字符数组的拷贝操作实现的。其实两个字符串相加的本质也是StringBuilder的方式相加的,但是会创建多余的字符串对象。


    String.format的源码
          核心实体的初始化,可以看到创建了一个StringBuilder作为了Formatter的全局变量。
    public Formatter() {
    this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
    }
    1
    2
    3
    具体实现

    public Formatter format(Locale l, String format, Object ... args) {
    ensureOpen();

    // index of last argument referenced
    int last = -1;
    // last ordinary index
    int lasto = -1;

    FormatString[] fsa = parse(format);
    for (int i = 0; i < fsa.length; i++) {
    FormatString fs = fsa[i];
    int index = fs.index();
    try {
    switch (index) {
    case -2: // fixed string, "%n", or "%%"
    fs.print(null, l);
    break;
    case -1: // relative index
    if (last < 0 || (args != null && last > args.length - 1))
    throw new MissingFormatArgumentException(fs.toString());
    fs.print((args == null ? null : args[last]), l);
    break;
    case 0: // ordinary index
    lasto++;
    last = lasto;
    if (args != null && lasto > args.length - 1)
    throw new MissingFormatArgumentException(fs.toString());
    fs.print((args == null ? null : args[lasto]), l);
    break;
    default: // explicit index
    last = index - 1;
    if (args != null && last > args.length - 1)
    throw new MissingFormatArgumentException(fs.toString());
    fs.print((args == null ? null : args[last]), l);
    break;
    }
    } catch (IOException x) {
    lastException = x;
    }
    }
    return this;
    }
          这下我们就明白了,原来String.format也是通过StringBuilder来时实现的。通过上面分析我们可以得出这样的结论:StringBuilder是其他两种方式的基础实现,所以还是StringBuilder比较占优势。

    总结:
          用+的方式效率最差,concat由于是内部机制实现,比+的方式好了不少。Join 和 StringBuffer,相差不大,Join方式要快些,可见这种JavaScript中快速拼接字符串的方式在Java中也非常适用。StringBuilder 的速度最快,但其有线程安全的问题,而且只有JDK5支持。
    ---------------------
    作者:笑破苍穹
    来源:CSDN
    原文:https://blog.csdn.net/u010168160/article/details/52021652
    版权声明:本文为博主原创文章,转载请附上博文链接!

    转发自:https://blog.csdn.net/u010168160/article/details/52021652

  • 相关阅读:
    Qt Creator编译问题
    『重构--改善既有代码的设计』读书笔记----Move Method
    『重构--改善既有代码的设计』读书笔记----Substitute Algorithm
    『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object
    『重构--改善既有代码的设计』读书笔记----Remove Assignments to Parameters
    『重构--改善既有代码的设计』读书笔记----Split Temporary Variable
    Qt信号槽连接在有默认形参下的情况思考
    巧用Session Manager还原Firefox丢失会话
    『重构--改善既有代码的设计』读书笔记----代码坏味道【5】
    『重构--改善既有代码的设计』读书笔记----代码坏味道【4】
  • 原文地址:https://www.cnblogs.com/PengChengLi/p/10299334.html
Copyright © 2020-2023  润新知