在Java开发者中,字符串的拼接占用资源高往往是热议的话题.

让我们深入讨论一下为什么会占用高资源。

在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它。所以在我们拼接字符串的时候,创建了一个新的字符串,旧的被垃圾回收器所标记。

如果我们处理上百万的字符串,然后,我们就会生成百万的额外字符串被垃圾回收器处理。

虚拟机底层在拼接字符串时执行了众多操作。拼接字符串最直接的点操作(dot operator)就是String#concat(String)操作。

  1. public String concat(String str) {
  2. int otherLen = str.length();
  3. if (otherLen == 0) {
  4. return this;
  5. }
  6. int len = value.length;
  7. char buf[] = Arrays.copyOf(value, len + otherLen);
  8. str.getChars(buf, len);
  9. return new String(buf, true);
  10. }
  11. public static char[] copyOf(char[] original, int newLength) {
  12. char[] copy = new char[newLength];
  13. System.arraycopy(original, 0, copy, 0,
  14. Math.min(original.length, newLength));
  15. return copy;
  16. }
  17. void getChars(char dst[], int dstBegin) {
  18. System.arraycopy(value, 0, dst, dstBegin, value.length);
  19. }

你可以看到一个字符数组被创建,长度则是已有字符和拼接的字符长度之和。然后,它们的值复制到新的字符数组中。最后,用这个字符数组创建一个String对象并返回。

所以这些操作繁多,如果你计算一下,会发现是O(n^2)的复杂度。

为了解决这个问题,我们使用StringBuilder类。它就像可变的String类。拼接方法帮助我们避免不必要的复制。它拥有O(n)的复杂度,远远优于O(n^2)。

然而Java 8默认使用StringBuilder拼接字符串。

Java 8的文档说明:

为了提高字字符串拼接的性能,Java编译器可以使用StringBuffer类或类似技术,在使用求值表达式时,减少中间String对象的创建。

Java编译器处理这种情况:

  1. public class StringConcatenateDemo {
  2. public static void main(String[] args) {
  3. String str = "Hello "; str += "world";
  4. }
  5. }

上面的代码会被编译成如下字节码:

  1. public class StringConcatenateDemo {
  2. public StringConcatenateDemo();
  3. Code:
  4. 0: aload_0
  5. 1: invokespecial #1                  // Method java/lang/Object."<init>":()V
  6. 4: return
  7. public static void main(java.lang.String[]);
  8. Code:
  9. 0: ldc           #2                  // String Hello
  10. 2: astore_1
  11. 3: new           #3                  // class java/lang/StringBuilder
  12. 6: dup
  13. 7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
  14. 10: aload_1
  15. 11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  16. 14: ldc           #6                  // String world
  17. 16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  18. 19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  19. 22: astore_1
  20. 23: return
  21. }

你可以在这些字节码中看到,使用了StringBuilder。所以我们在Java 8中不再需要使用StringBuilder类。

译文链接:http://www.codeceo.com/article/why-java8-not-use-stringbuilder.html
英文原文:We Don't Need StringBuilder for Concatenation Anymore
翻译作者:码农网 – 孙腾浩

为什么Java 8中不再需要StringBuilder拼接字符串相关推荐

  1. java8 stringbuilder_为什么 Java 8 中不再需要 StringBuilder 拼接字符串

    在Java开发者中,字符串的拼接占用资源高往往是热议的话题. 让我们深入讨论一下为什么会占用高资源. 在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它.所以在我们拼接字符串的时候 ...

  2. java8 stringbuilder_为什么 Java 8 中不需要 StringBuilder 拼接字符串

    在Java开发者中,字符串的拼接占用资源高往往是热议的话题. 让我们深入讨论一下为什么会占用高资源. 在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它.所以在我们拼接字符串的时候 ...

  3. c++ 字符串拼接_源码上看 .NET 中 StringBuilder 拼接字符串的实现

    专注分享C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协 ...

  4. 站长在线python精讲:在Python中使用“+”运算符来拼接字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用"+"运算符来拼接字符串详解>.本知识点主要内容有:在Python中,我们可以使用& ...

  5. Java中如何高效的拼接字符串

    目录 写在前面 常规的字符串拼接方法 写在前面 这是一篇非常基础的文章,将会演示如何使用Java正确高效的拼接字符串. 这些问题也是我们应该注意的基础的性能优化技巧. 常规的字符串拼接方法 使用'+' ...

  6. JavaSE——StringBuffer与StringBuilder拼接字符串详细解释

    目录 一.基本了解 1.1使用字符串频繁拼接会出现什么问题? 1.2  了解StringBuffer 1.3 了解StringBuilder 1.4 StringBuffer与StringBuilde ...

  7. JAVA语言中数字、字符和字符串处理

    前言: JAVA语言中针对数字.数学运算.字符.字符串有专门的类,分别是Number.Math.Character和String. 1.数字: JAVA对数字处理的相关方法被封装在java.lang包 ...

  8. java addslashes_PHP中addslashes()和stripslashes()实现字符串转义和还原用法实例

    本文实例讲述了PHP中addslashes()和stripslashes()实现字符串转义和还原用法.分享给大家供大家参考,具体如下: PHP中addslashes() 函数返回在预定义字符之前添加反 ...

  9. Java黑皮书课后题第10章:**10.28(实现StringBuilder类)在Java库中提供了StringBuilder类。给出你对下面方法的实现(将新类命名为MyStringBuilder2)

    题目 代码 public class Test28_MyStringBuilder2 {String s = "";// 无参构造方法public Test28_MyStringB ...

最新文章

  1. Java入门(一):Hello World !
  2. kafka消息的分发与消费(一)
  3. 【C语言】switch…case无break情况(2)
  4. PRD:「FITLIFE」小程序产品需求文档(用户端)
  5. 《转载》struts旅程《2》
  6. 常用类 (七) ----- 包装类
  7. python连接数据库oracle_python 连接oracle数据库:cx_Oracle
  8. 编程推荐的好看、护眼字体
  9. Foxit PDF SDK for iOS--零基础Cordova开发
  10. 文件管理之:打包、压缩
  11. 网络性能指标及测试方法
  12. mysql创建数据库表bank_数据库创建表fk
  13. 数据中心机房温湿度监测
  14. 根据E-R图设计数据库表
  15. Centos 7 grub 菜单加密以及取消加密
  16. 南京信息工程大学第十届程序设计大赛试题
  17. Jedis使用lua脚本完成令牌桶限流
  18. 京东2019校园招聘笔试+面试(算法工程师岗位)
  19. php最快的学习路线
  20. iPhone弱网测试

热门文章

  1. 李宏毅深度学习——深度学习介绍
  2. Sklearn(v3)——SVM理论(1)
  3. vue实战第一课:天气查询
  4. 百度工程师深度好文, 横评3大企业级区块链技术平台
  5. 梯度下降法(一)入门
  6. 巴黎事件发生后,Facebook、Twitter、Google和Uber都做了什么?
  7. Oracle海量数据优化-02分区在海量数据库中的应用-更新中
  8. 【动态数组】数据结构01-(java实现)
  9. 计算机应用与技术网上测试题答案,计算机应用与技术网上测试题.doc
  10. 4.通过三个交换机实现VLAN间通信