为什么 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类的帮助 ...
随机推荐
- JS高程3.基本概念(4)操作符
ECMA-262用于操作数据值的操作符包括: 算术操作符 位操作符 关系操作符 相等操作符 ECMAScript操作符的不同之处在于:它能够适用于很多值,包括字符串,数字值,布尔值,甚至是对象.(在应 ...
- 关于在线编辑器的选择:tinymce - nilcms
一开始使用的是百度开发的编辑器:ueditor.使用方便,很容易就部署了.现在发现此编辑器也就做一些安全性的更新,而且对于这个编辑器也越来越不喜欢了. 1.臃肿.[1.4.3.3 PHP 版本].下载 ...
- 一些有用的SAP技术TCODE
Background Processing RZ01 Job Scheduling Monitor SM36 Schedule Background Job SM36WIZ Job definitio ...
- JAVA简单工厂模式(从现实生活角度理解代码原理)
简单工厂模式(Simple Factory),说他简单是因为我们可以将此模式比作一个简单的民间作坊,他们只有固定的生产线生产固定的产品.也可以称他为静态工厂设计模式,类似于之前提到过静态代理设计模式, ...
- 三种POST和GET的提交方式
向服务器提交数据有两种方式,post和get.两者的区别主要有三点,安全性.长度限制.数据结构.其中get请求安全性相比较而言较差,数据长度受浏览器地址栏限制,没有方法体.两种都是较为重要的数据提交方 ...
- 开发者调试工具Chrome Workspace
Workspace是个什么样的东西呢?他能够在开发者工具中调试修改js或者css同时自动保存文件,能够避免开发人员在工具中调试好,再到编辑器中修改一次代码的重复操作,能够提高一定的效率 配置Chrom ...
- SQL Server 使用OPENROWSET访问ORACLE遇到的各种坑总结
在SQL Server中使用OPENROWSET访问ORACLE数据库时,你可能会遇到各种坑,下面一一梳理一下你会遇到的一些坑. 1:数据库没有开启"Ad Hoc Distributed Q ...
- mac xcode c++ cin cout注意细节一
#include <iostream> using namespace std; 要同时存在 要不然std命名空间无法生效
- linux shell取文本最后一行
目前我知道的方法有四种 1.awk 'END {print}' 2.sed -n '$p' 3.sed '$!N;$!D' 4.awk '{b=a"\n"$0;a=$0 ...
- 你们信不信一句Console.WriteLine就能让你的控制台程序失去响应
好久没更新博客了,今天是扒衣见君节,难得闲下来就来说说一个最近有趣的发现吧. 首先废话不多说,直接上代码吧 class Program { static void Main(string[] args ...
