为什么 Java 8 中不需要 StringBuilder 拼接字符串

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

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

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

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

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

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);
}
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;
}
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编译器处理这种情况:

public class StringConcatenateDemo {
public static void main(String[] args) {
String str = "Hello ";
str += "world";
}
}

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

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类。

英文原文:We Don't Need StringBuilder for Concatenation Anymore

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java StringBuffer类与StringBuilder类用法实例小结

    本文实例总结了Java StringBuffer类与StringBuilder类用法.分享给大家供大家参考,具体如下: StringBuffer类的构造方法 package cn.itcast_01; /* * 线程安全(多线程讲解) * 安全 -- 同步 -- 数据是安全的 * 不安全 -- 不同步 -- 效率高一些 * 安全和效率问题是永远困扰我们的问题. * 安全:医院的网站,银行网站 * 效率:新闻网站,论坛之类的 * * StringBuffer: * 线程安全的可变字符串. * *

  • java 中String和StringBuffer与StringBuilder的区别及使用方法

    java 中String和StringBuffer与StringBuilder的区别及使用方法 1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a"; //假设a指向地址0x0001 a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向

  • Java中字符数组和字符串与StringBuilder和字符串转换的讲解

    1.字符串->字符数组: String str = "abc": char[] a = str.toCharArray(); 记忆:字符串是个类,所以用内建函数 延伸: char b = str.charAt(1); str.length(); a.length; 2.字符数组->字符串: String str = String.valueOf(a): 记忆:类似强制类型转换格式,String(a) 延伸:字符转字符类 Character c = Character.val

  • java StringBuilder类的详解及简单实例

     java  StringBuilder类的详解及简单实例 实现代码: public class StringBuilderTest { /** * @param args */ public static void main(String[] args) { StringBuilder sb = new StringBuilder(); // 追加字符串 sb.append("java");//sb = "java" // 插入 sb.insert(0 , &qu

  • 为什么 Java 8 中不需要 StringBuilder 拼接字符串

    在Java开发者中,字符串的拼接占用资源高往往是热议的话题. 让我们深入讨论一下为什么会占用高资源. 在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它.所以在我们拼接字符串的时候,创建了一个新的字符串,旧的被垃圾回收器所标记. 如果我们处理上百万的字符串,然后,我们就会生成百万的额外字符串被垃圾回收器处理. 虚拟机底层在拼接字符串时执行了众多操作.拼接字符串最直接的点操作(dot operator)就是String#concat(String)操作. public Stri

  • 详解.NET中string与StringBuilder在字符串拼接功能上的比较

    string与StringBuilder的在字符串拼接时执行效率上有差异,因为StringBuilder类中用了一个技巧:它申请了两倍的内存空间存放字符串,在调用Append方法拼接字符串时,会先检查剩余的空间是否能放下要拼接的字符串,若能放下,则将要拼接的字符串Copy到剩余的空间中,若不能放下,则再申请拼接后的字符串两倍的长度空间,将当前字符串Copy到新的空间中(除了两倍的空间外,这点跟string的拼接没有太多的差异).因此StringBuilder能提高字符串拼接的效率在于它减少了申请

  • MyBatis中正则使用foreach拼接字符串

    目录 正则使用foreach拼接字符串 foreach标签拼接多字段in ,和union 正则使用foreach拼接字符串 业务需求:使用代理名字查询该代理的所有下级代理 数据库: pid存储的是该字段的上级集合 实现步骤: 1.先用名字在用户表中查询出用户id集合 2.在数据库中判断字段pids中是否出现这些id,再去重 -------上重点-------: 在mybatis中写拼接这个sql碰到了很多坑,记录下这个教训: 1.foreach拼接字符串,开头和结尾用单引号,否则报错 2.中括号

  • JavaScript中使用concat()方法拼接字符串的教程

    这种方法将两个或多个字符串,并返回一个新的单字符串. 语法 string.concat(string2, string3[, ..., stringN]); 下面是参数的详细信息: string2...stringN : 这些是要连接字符串. 返回值: 返回一个连接字符串. 例子: <html> <head> <title>JavaScript String concat() Method</title> </head> <body>

  • Java基础之String类使用与字符串比较

    目录 一.String类概述 二.String类的特点 三.String类的构造方法 四.创建字符串对象两种方式的区别 五.字符串的比较 六.用户登录案例 一.String类概述 String类代表字符串,java程序中的所有字符串文字(例如"abc")都被实现为此类的实例.也就是说,java程序中所有的双引号字符串,都是String类的对象. String类在java.lang包下,所有使用的时候不需要导包! 二.String类的特点 字符串不可变,它们的值在创建后不能被更改 虽然S

  • 从内存方面解释Java中String与StringBuilder的性能差异

    以前经常在网上看到关于Java字符串拼接等方面的讨论.看到有些Java开发人员在给新手程序员的建议中类似如下写道: 不要使用+号拼接字符串,要使用StringBuffer或StringBuilder的append()方法来拼接字符串. 不过,用+号拼接字符串就真的那么令人讨厌,难道使用+号拼接字符串就没有一点可取之处吗? 通过查阅Java API文档中关于String类的部分内容,我们可以看到如下片段: "Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串

  • Java 8中字符串拼接新姿势StringJoiner详解

    在为什么阿里巴巴不建议在for循环中使用"+"进行字符串拼接一文中,我们介绍了几种Java中字符串拼接的方式,以及优缺点.其中还有一个重要的拼接方式我没有介绍,那就是Java 8中提供的StringJoiner ,本文就来介绍一下这个字符串拼接的新兵. 如果你想知道一共有多少种方法可以进行字符串拼接,教你一个简单的办法,在Intellij IDEA中,定义一个Java Bean,然后尝试使用快捷键自动生成一个toString方法,IDEA会提示多种toString生成策略可供选择. 1

  • Java代码中4种字符串拼接方式分析

    目录 结论 最佳实践 分析过程 环境 分析用示例代码: 代码及结果分析 本文研讨的字符串拼接方式为以下4种:“+”号.StringBuilder.StringJoiner.String#join,对比分析及探讨最佳实践. 结论 后面内容比较枯燥,所以先说结论: 本文研讨的字符串拼接方式为以下4种:“+”号.StringBuilder.StringJoiner.String#join 在简单的字符串拼接场景中「如:"a" + "b" + "c"」,

  • Java中拼接字符串String的N种方法总结

    目录 1.前言 2.问题复现 3.使用+运算符 4.使用String.concat() 5.使用StringBuilder 6.使用StringJoiner类(Java8+) 7.使用Streams.filter(Java8+) 8.总结 1. 前言 Java 提供了拼接 String 字符串的多种方式,不过有时候如果我们不注意 null 字符串的话,可能会把 null 拼接到结果当中,很明显这不是我们想要的. 在这篇文章中,将介绍一些在拼接 String 时避免 null 值的几种方式. 2.

  • 浅析Java中String与StringBuffer拼接的区别

    学习笔记: 1.String拼接会创建一个新的String对象,存储拼接后的字符串: StringBuffer拼接是直接在本身拼接,会即时刷新. 2.String只能拼接String类型的字符串: StringBuffer能够拼接所有的类型的值. public class Test { public static void main(String[] args) { String str1="abc"; String str2="cba"; //使用Stirng的c

随机推荐