为什么 Java 8 中不再需要 StringBuilder 拼接字符串
为什么 Java 8 中不再需要 StringBuilder 拼接字符串
在Java开发者中,字符串的拼接占用资源高往往是热议的话题.
让我们深入讨论一下为什么会占用高资源。
在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它。所以在我们拼接字符串的时候,创建了一个新的字符串,旧的被垃圾回收器所标记。
如果我们处理上百万的字符串,然后,我们就会生成百万的额外字符串被垃圾回收器处理。
虚拟机底层在拼接字符串时执行了众多操作。拼接字符串最直接的点操作(dot operator)就是String#concat(String)操作。
1
2
3
4
5
6
7
8
9
10
|
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0 ) { return this ; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true ); } |
1
2
3
4
5
6
|
public static char [] copyOf( char [] original, int newLength) { char [] copy = new char [newLength]; System.arraycopy(original, 0 , copy, 0 , Math.min(original.length, newLength)); return copy; } |
1
2
3
|
void getChars( char dst[], int dstBegin) { System.arraycopy(value, 0 , dst, dstBegin, value.length); } |
你可以看到一个字符数组被创建,长度则是已有字符和拼接的字符长度之和。然后,它们的值复制到新的字符数组中。最后,用这个字符数组创建一个String对象并返回。
所以这些操作繁多,如果你计算一下,会发现是O(n^2)的复杂度。
为了解决这个问题,我们使用StringBuilder类。它就像可变的String类。拼接方法帮助我们避免不必要的复制。它拥有O(n)的复杂度,远远优于O(n^2)。
然而Java 8默认使用StringBuilder拼接字符串。
Java 8的文档说明:
为了提高字字符串拼接的性能,Java编译器可以使用StringBuffer类或类似技术,在使用求值表达式时,减少中间String对象的创建。
Java编译器处理这种情况:
1
2
3
4
5
6
|
public class StringConcatenateDemo { public static void main(String[] args) { String str = "Hello " ; str += "world" ; } } |
上面的代码会被编译成如下字节码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class StringConcatenateDemo { public StringConcatenateDemo(); Code: 0 : aload_0 1 : invokespecial # 1 // Method java/lang/Object."<init>":()V 4 : return public static void main(java.lang.String[]); Code: 0 : ldc # 2 // String Hello 2 : astore_1 3 : new # 3 // class java/lang/StringBuilder 6 : dup 7 : invokespecial # 4 // Method java/lang/StringBuilder."<init>":()V 10 : aload_1 11 : invokevirtual # 5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14 : ldc # 6 // String world 16 : invokevirtual # 5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19 : invokevirtual # 7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22 : astore_1 23 : return } |
你可以在这些字节码中看到,使用了StringBuilder。所以我们在Java 8中不再需要使用StringBuilder类。
为什么 Java 8 中不再需要 StringBuilder 拼接字符串的更多相关文章
- 源码上看 .NET 中 StringBuilder 拼接字符串的实现
前几天写了一篇StringBuilder与TextWriter二者之间区别的文章(链接).当时提了一句没有找到相关源码,于是随后有很多热心人士给出了相关的源码链接(链接),感谢大家.这几天抽了点时间查 ...
- 2、Java应用中常见的JDBC连接字符串(SQLite、MySQL、Oracle、Sybase、SQLServer、DB2)
2.Java应用中常见的JDBC连接字符串 Java应用中连接数据库是不可或缺的,于是便整理一些可能用到的JDBC的jar包及其相匹配的URL,以备日后查阅. 1)SQLite Class.forNa ...
- java以逗号为分割符拼接字符串的技巧
java以逗号为分割符拼接字符串的技巧 答: 不用那么多if判断,让人思维混乱,直接到最后使用deleteCharAt方法去除最后一个逗号即可. 实现代码如下所示: StringBuffer sb ...
- 【JVM】Java 8 中的常量池、字符串池、包装类对象池
1 - 引言 2 - 常量池 2.1 你真的懂 Java的“字面量”和“常量”吗? 2.2 常量和静态/运行时常量池有什么关系?什么是常量池? 2.3 字节码下的常量池以及常量池的加载机制 2.4 是 ...
- C# 拼接字符串的几种方式和性能
开发过程中常用到的拼接字符串的方法有三种: 1 简单 “+=” 拼接法 1 2 3 4 5 string str="a"; str+="c"+"d ...
- 昨天还在for循环里写加号拼接字符串的那个同事,今天已经不在了
引言 都说 StringBuilder 在处理字符串拼接上效率要强于 String,但有时候我们的理解可能会存在一定的偏差.最近我在测试数据导入效率的时候就发现我以前对 StringBuilder 的 ...
- 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接
长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...
- Java基础学习总结(65)——Java中的String,StringBuilder和StringBuffer比较
字符串,就是一系列字符的集合. Java里面提供了String,StringBuffer和StringBuilder三个类来封装字符串,其中StringBuilder类是到jdk 1.5才新增的.字符 ...
- Java 8中字符串拼接新姿势:StringJoiner
介绍 StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾.虽然这也可以在StringBuilder类的帮助 ...
随机推荐
- jquery插件图片延时加载实例详解
效果预览:http://keleyi.com/keleyi/phtml/image/index.htm 使用方法:1.导入JS插件 <script src="http://keleyi ...
- jQuery切换网页皮肤保存到Cookie实例
效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/25.htm 以下是源代码: <!DOCTYPE html PUBLIC "-//W3C//D ...
- 软件开发流程 Software development process
软件开发流程(Software development process)即软件设计思路和方法的一般过程,包括设计软件的功能和实现的算法和方法.软件的总体结构设计和模块设计.编程和调试.程序联调和测试以 ...
- JQ中的方法、事件及动画
css( ) 除了可以为元素添加样式外,还可用来查询元素,某样式值alert($('.cls1').css('width')); //100px(返回带单位的值)注意:原生CSS样式中有-的去掉并且将 ...
- 编写可维护的CSS
在参与规模庞大.历时漫长且参与人数众多的项目时,所有开发者遵守如下规则极为重要: 保持 CSS 便于维护 保持代码清晰易懂 保持代码的可拓展性 为了实现这一目标,我们要采用诸多方法. 本文档第一部分将 ...
- php中用foreach改变数组的值的问题
翻到PHP文档的foreach那页这样写道: “foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误 ...
- 长链接转换成短链接(iOS版本)
首先需要将字符串使用md5加密,添加NSString的md5的类别方法如下 .h文件 #import <CommonCrypto/CommonDigest.h> @interface NS ...
- 敏捷开发与jira之研发管理模式
以IPD方法论为基础,采用原型+迭代的开发模式,并以质量优先为原则,持续对用户做价值交付. 使用JIRA+WIKI+SVN管理整个的研发过程:JIRA管理任务和进度:SVN管理代码和过程文档:WIKI ...
- [css]我要用css画幅画(八) - Hello Kitty
接着之前的[css]我要用css画幅画(七) - 哆啦A梦,这次画的是Hello Kitty. /* 开始前先说点废话, 一转眼就2016年了,过完年后一直没更新博客,无他,就是懒得动. 这一转眼,一 ...
- C#中Split用法
1.用字符串分隔: using System.Text.RegularExpressions; string str="aaajsbbbjsccc"; string[] sArr ...