为什么 Java 8 中不需要 StringBuilder 拼接字符串
- 更新时间:2022-10-19 08:59:36
- 编辑:通谷丝
参考资料
- Java Web编程技术 课后答案 / 1.41 MB / 沈泽刚 秦玉平 推荐度:
- 深入理解Java核心技术:写给Java工程师的干货笔记(基础篇) PDF 电子书 / 97.6 MB / 张洪亮(@Hollis) 推荐度:
- Java ME手机应用开发技术与案例详解 PDF 电子书 / 22.45MB / 冼进,文扬 推荐度:
正文内容
在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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。
Java相关教程
-
Java并发编程之对象的共享
给大家整理一篇关于Java 并发的教程,这篇文章主要介绍了Java并发编程之对象的共享,介绍如何共享和发布对象,使它们被安全地由多个进程访问。需要的小伙伴可以参考一下
发布时间:2022-09-14
-
Java中ClassLoader类加载原理用法
本篇文章主要给大家讲述了Java中ClassLoader类加载的原理以及用法总结,一起学习下。
发布时间:2019-06-23
-
Java设计模式之原型模式Prototype
这篇文章主要为大家详细介绍了Java设计模式之Prototype原型模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
发布时间:2020-01-27
-
Java远程共享目录的操作详解
这篇文章主要介绍了java操作远程共享目录的实现代码,非常不粗,具有参考借鉴价值,需要的朋友可以参考下
发布时间:2020-02-04
-
解决java向mysql插入数据乱码的方法
这篇文章主要为大家详细介绍了java向mysql插入数据乱码问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
发布时间:2021-06-02
-
java itext导出PDF功能实现
下面小编就为大家带来一篇java使用itext导出PDF文本绝对定位(实现方法)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
发布时间:2020-02-26
-
java计算掷6面骰子6000次每个点数出现的概率代码实例
今天小编就为大家分享一篇关于掷6面骰子6000次每个点数出现的概率,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
发布时间:2020-05-13
-
Java与Python中单例模式的区别
本文实例讲述了Java与Python中单例模式的区别。分享给大家供大家参考,具体如下:
发布时间:2021-04-27
-
详解JAVA随机生成指定长度的密码功能(包含大小写和数字组合)
这篇文章主要介绍了JAVA编程实现随机生成指定长度的密码功能,可生成带有大小写和数字组合的随机字符串,需要的朋友可以参考下
发布时间:2020-02-22