今日我在阅读阿里巴巴开发手册泰山版,发现开发手册上有这么一条:【推荐】 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

字符串的三种表示类型

String类型

String是不可变类型。 下面是jdk11里面String类的源码,String的成员变量有value和hash。value是一个引用,指向String封装的数组对象。value是被private final修饰的,并且没有提供setvalue等用于修改值的公共方法。所以String是不可变的。

public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];/** Cache the hash code for the string */private int hash; // Default to 0}

每次对String的操作,一旦修改String对象,都会生成新的String对象。下面是String类中的replace()函数,每次修改String函数会调用,并return new String(buf, true);因此在循环体中,使用String进行连接不仅效率低下,而且造成内存资源浪费。

 /*** Returns a string resulting from replacing all occurrences of* {@code oldChar} in this string with {@code newChar}.** @param   oldChar   the old character.* @param   newChar   the new character.* @return  a string derived from this string by replacing every*          occurrence of {@code oldChar} with {@code newChar}.*/public String replace(char oldChar, char newChar) {if (oldChar != newChar) {int len = value.length;int i = -1;char[] val = value; /* avoid getfield opcode */while (++i < len) {if (val[i] == oldChar) {break;}}if (i < len) {char buf[] = new char[len];for (int j = 0; j < i; j++) {buf[j] = val[j];}while (i < len) {char c = val[i];buf[i] = (c == oldChar) ? newChar : c;i++;}return new String(buf, true);//生成新的String对象}}return this;}

StringBuffer类型

StringBuffer类是线程安全的可变数据类型,继承于 AbstractStringBuilder类。

下面是jdk11里面StringBuffer类的源码。StringBuffer类具体实现了可变字符序列的操作比如append()、insert()、delete()、replace()、charAt()等。这些方法都被sychronized修饰,是线程安全的。

StringBuffer是线程安全的可变数据类型。StringBuffer类的对象能够被多次的修改,并且不产生新的未使用对象。对于不要求线程安全或者单线程的情况下,StringBuffer因为线程加锁导致性能损耗,所以在循环体中,使用StringBuffe效率低。

StringBuilder类型

StringBuilder是线程不安全的可变数据类型。与StringBuffer类一样,继承于 AbstractStringBuilder类。

下面是jdk11里面StringBuffer类的源码。StringBuffer类具体实现了可变字符序列的操作比如append()、insert()、delete()、replace()、charAt()等。与StringBuffer不同,这些方法没有加锁,不能降低性能,所以手册中建议使用StringBuilder。

String、StringBuilder和StringBuffer的性能测试

测试代码如下:

/*** <p>测试String、StringBuilder和StringBuffer的性能</p>** @author : cxc* @date : 2020-06-22 01:56**/
public class Test {public static Runtime runtime = Runtime.getRuntime();public static void main(String[] args) {long maxMemory = runtime.maxMemory();System.out.println("最大内存: " + maxMemory/1024/1024 + "M");int [] times = {10000, 100000, 1000000, 10000000, 100000000, 1000000000};for (int i : times) {System.out.println("循环执行次数:" + i);StringTest(i);StringBuilderTest(i);StringBufferTest(i);System.out.println();}}private static void StringTest(int times){String sbd = "";long start = System.currentTimeMillis();while (sbd.length() < times) {sbd += "a";}System.out.println("String执行时间:" + (System.currentTimeMillis() - start)+"ms");System.out.println("String使用内存: " + (runtime.totalMemory() - runtime.freeMemory())/1024/1024 + "M");}private static void StringBuilderTest(int times){StringBuilder sbd = new StringBuilder();long start = System.currentTimeMillis();while (sbd.length() < times) {sbd.append("a");}System.out.println("StringBuilder执行时间:" + (System.currentTimeMillis() - start)+"ms");System.out.println("StringBuilder使用内存: " + (runtime.totalMemory() - runtime.freeMemory())/1024/1024 + "M");}private static void StringBufferTest(int times){StringBuffer sbf = new StringBuffer();long start = System.currentTimeMillis();while (sbf.length() < times) {sbf.append("a");}System.out.println("StringBuffer执行时间:" + (System.currentTimeMillis() - start)+"ms");System.out.println("StringBuffer使用内存: " + (runtime.totalMemory() - runtime.freeMemory())/1024/1024 + "M");}
}

执行结果如下:随着循环次数的增长,在循环体中StringBuilder的性能优势越来越明显。

参考链接:

https://blog.csdn.net/weixin_41101173/article/details/79677982

文章持续更新,可以微信搜索「 云璈公子 」阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板,同时我的GitHub https://github.com/1170300826/JavaInterview 有互联网一线大厂面试指南。

(阿里巴巴开发手册)为什么阿里巴巴推荐内部员工使用StringBuilder?相关推荐

  1. 阿里巴巴开发手册“泰山”版它来了,1.4.0+终极版+阿里内部PPT

    阿里的<Java开发手册>距离上次发布已经过去了 10 个月了,而这次发布也增加了很多干货内容,比如:新增 34 条规约,修改描述 90 处,其中错误码规则更是第一次提出完整的解决方案,发 ...

  2. 关于阿里巴巴开发手册不得使用外键与级联,一切外键概念必须在应用层解决的疑惑

    原文地址:http://www.codes51.com/itwd/4517194.html 问题: 关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑 ...

  3. 全套阿里巴巴开发手册和大神解读一起给你【2022年整理】

    前些日子查些资料想要看一下阿里巴巴开发手册,网上一搜出来了一大推,也搞不清楚哪个,更让人讨厌的是有很多介绍开发手册文章的是某些培训机构来吸引流量的,都能看得来的写文章的人根本不懂这些东西,最后放个二维 ...

  4. 阿里巴巴开发手册笔记整理

    长久以来,一直有一个愿望,就是自己能够遵循某种规范进行实践,或者说能找一个比较经得起实践的理论来指导.  直到我们老师给我们推荐了阿里巴巴开发手册,大概看了看目录,嗯 ,  是我想要的.于是,这里就趁 ...

  5. 阿里巴巴开发手册最新版、码出高效、性能调优实战、成神之路

    清幽现云山, 虚静出内功 <阿里巴巴Java开发手册>是阿里内部Java工程师所遵循的开发规范,涵盖编程规约.单元测试规约.异常日志规约.MySQL规约.工程规约.安全规约等,这是近万名阿 ...

  6. 魔法值是什么?(为什么在阿里巴巴开发手册中提到不允许任何魔法值直接出现在代码中)

    在阿里巴巴开发手册中,提到魔法值,是在最开始的常量定义中提到的.即如下图: 那么,魔法值究竟是什么? 在al手册中说是未经预先定义的常量. 其实这样说就已经很明了了,但毕竟是一个不常见的概念,所以我在 ...

  7. 包机制、阿里巴巴开发手册

    公司域名倒置作为包名 com.baidu.www 阿里巴巴开发手册可百度搜索看看

  8. Java阿里巴巴开发手册与JDK1.8API中文版下载

    Java阿里巴巴开发手册 JDK1.8API中文版 链接:https://pan.baidu.com/s/1M3zp31KlRCXDXkBqHSUS6A 提取码:lcmc

  9. 阿里巴巴开发手册之应用分层

    阿里巴巴开发手册自己所感 应用分层 总结:其实,对于*****的开放接口设计来说,manager层实在 业务逻辑层之上的,区别并不是很大,但是service 和 manager 可以互相转化 ,就数据 ...

最新文章

  1. STL笔记(5)条款49:学习破解有关STL的编译器诊断信息
  2. 「x is All You Need」,当学术论文开始标题党……
  3. Deep Learning回顾#之LeNet、AlexNet、GoogLeNet、VGG、ResNet
  4. sybase存储过程修改
  5. java native内存_android java内存与native内存
  6. 【转】Go 语言教程(2)——表达式
  7. sizeof 的结果取决于什么
  8. 基于对偶学习的跨领域图片描述生成
  9. Boost:求容器的最小元素和最大元素
  10. CodeForces 501B——Misha and Changing Handles
  11. NodeJS 常用模块积累
  12. Oracle EBS-SQL (OM-2):检查OM常用表
  13. 【深入理解Nginx】Nginx的配置
  14. 5s管理中清扫的内容及实施步骤
  15. mac修改hosts刷新DNS使其立即生效
  16. ML-Agents案例之机器人学走路
  17. 跨境电商供应链难点有哪些?
  18. Scratch编程 烧脑算法——换位密码
  19. ndnSIM学习(八)——examples之ndn-simple.cpp每个函数逐行剖析
  20. allure报告中去掉allure.title中自动拼接的参数

热门文章

  1. 独步天下的创业历险记6-一叶知秋
  2. SAP EWM TCODE list
  3. USTC English Club Note20211227
  4. CSDN写博客修改图片大小、图片居中、去掉图片水印等方法
  5. 浅谈信息安全的职业发展方向规划(乙方安全公司篇)
  6. python中美元人汇率_Python获取美元人民币实时汇率
  7. 美国将派大量自动昆虫机器人到火星执行任务
  8. Pytho读取Xml文件
  9. git检出新分支遇到的文件路径过长Filename too long的问题
  10. 零基础如何快速学习Java?Java基础入门秘诀