一、简单介绍

编写代码过程中,使用"+"和"contact"比较普遍,但是它们都不能满足大数据量的处理,一般情况下有一下四种方法处理字符串拼接,如下:

1、 加号"+"

2、 Stringcontact()方法

3、 StringBufferappend()方法

4、 StringBuilderappend()方法

二、测试代码参考

StringTest

package com.jdk8.event.StringTest;

public class StringTest {
private static final int max = 100000; public static void testPlus() {
System.out.println("************ plusTest() ************"); String str = ""; long start = System.currentTimeMillis(); for (int i = 0; i < max; i++) {
str = str + "a";
} long end = System.currentTimeMillis(); long cost = end - start; System.out.println(" {str + \"a\"} cost=" + cost + " ms");
} public static void testConcat() {
System.out.println("************ concatTest() ************"); String str = ""; long start = System.currentTimeMillis(); for (int i = 0; i < max; i++) {
str = str.concat("a");
} long end = System.currentTimeMillis(); long cost = end - start; System.out.println(" {str.concat(\"a\")} cost=" + cost + " ms");
} public static void testStringBuffer() {
System.out.println("************ StringBufferTest() ************"); long start = System.currentTimeMillis(); StringBuffer strBuffer = new StringBuffer(); for (int i = 0; i < max; i++) {
strBuffer.append("a");
}
strBuffer.toString(); long end = System.currentTimeMillis(); long cost = end - start; System.out.println(" {strBuffer.append(\"a\")} cost=" + cost + " ms");
} public static void testStringBuilder() {
System.out.println("************ StringBuilderTest() ************"); long start = System.currentTimeMillis(); StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i < max; i++) {
strBuilder.append("a");
}
strBuilder.toString(); long end = System.currentTimeMillis(); long cost = end - start; System.out.println(" {strBuilder.append(\"a\")} cost=" + cost + " ms");
}
}

测试类:TestMain

package com.jdk8.event.StringTest;

public class TestMain {
public static void main(String[] args){
System.out.println("执行100次时");
StringTest.testPlus();
StringTest.testConcat();
StringTest.testStringBuffer();
StringTest.testStringBuilder();
}
}

测试结果如下:

执行100次时
************ plusTest() ************
{str + "a"} cost=0 ms
************ concatTest() ************
{str.concat("a")} cost=0 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=0 ms
************ StringBuilderTest() ************
{strBuilder.append("a")} cost=0 ms
执行1000次时
************ concatTest() ************
{str.concat("a")} cost=1 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=0 ms
************ StringBuilderTest() ************
{strBuilder.append("a")} cost=0 ms
执行10000次时
************ plusTest() ************
{str + "a"} cost=99 ms
************ concatTest() ************
Disconnected from the target VM, address: '127.0.0.1:63818', transport: 'socket'
{str.concat("a")} cost=17 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=1 ms
************ StringBuilderTest() ************
{strBuilder.append("a")} cost=0 ms
执行100000次时
************ plusTest() ************
{str + "a"} cost=6176 ms
************ concatTest() ************
{str.concat("a")} cost=1267 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=3 ms
************ StringBuilderTest() ************
Disconnected from the target VM, address: '127.0.0.1:63841', transport: 'socket'
{strBuilder.append("a")} cost=2 ms
执行300000次时
************ plusTest() ************
{str + "a"} cost=23554 ms
************ concatTest() ************
{str.concat("a")} cost=17667 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=6 ms
************ StringBuilderTest() ************
{strBuilder.append("a")} cost=5 ms
执行500000次时
************ plusTest() ************
{str + "a"} cost=61421 ms
************ concatTest() ************
{str.concat("a")} cost=53173 ms
************ StringBufferTest() ************
{strBuffer.append("a")} cost=9 ms
************ StringBuilderTest() ************
{strBuilder.append("a")} cost=7 ms

1、 方法1 "+"号和方法2 contact()方法适用于数据量比较小的情况下。为了操作代码风格和养成习惯,还是建议尽量不用

2、方法2 StringBufferappend()方法和StringBuilderappend()方法 本质上是一样的,均继承自AbstractStringBuilder抽象类,效率很高,数据量比较大的时候的推荐用法。区别是StringBuffer 是线程安全的,而StringBuilder是线程不安全的。

三、源代码分析

1、 String的"+"方法,编译器对其做了优化,使用StringBuilderappend()方法进行追加,但是每循环一次都会创建一个StringBuilder对象,且都会调用toString()方法转换为字符串,因此开销很大。

注:执行一次String的"+"方法,相当于str = new StringBuilder(str).append("x").toString();

2、调用Stringcontact()方法,其实就是一次数组的拷贝,虽然在内存中的处理都是原子操作,速度很快,但是当返回时是要创建一个新的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);
}

3、StringBufferStringBuilderappend()方法均主要使用父类AbstractStringBuilderappend()方法。源码如下:

    public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}

即当数组空间够用的时候,只是在数组后面添加字符或字符串,并不创建新的对象,只是到最后通过toString()方法来生成最终的字符串,效率很快,也很节省空间,是推荐的用法。

参考

https://www.cnblogs.com/twzheng/p/5923642.html

Java 字符串拼接四种方式的性能比较分析的更多相关文章

  1. Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次

    [请尊重原创版权,如需引用,请注明来源及地址] > 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现 ...

  2. Java 字符串拼接5种方式性能比较

    https://www.cnblogs.com/twzheng/p/5923642.html

  3. Java基础知识强化25:Java创建对象的四种方式

    1. Java程序中对象的创建有四种方式: ● 调用new语句创建对象,最常见的一种 ● 运用反射手段创建对象,调用java.lang.Class 或者 java.lang.reflect.Const ...

  4. PHP定义字符串的四种方式

    1.简介 在PHP中这门语言中,因为是弱类型语言,因此使用变量时不需提前定义即可使用. 我们在使用php进行开发的时候,大多数使用双引号.单引号进行定义字符串.既然有这两种方式,那么他们之间肯定是有区 ...

  5. C# 拼接字符串的几种方式和性能

    开发过程中常用到的拼接字符串的方法有三种: 1 简单 “+=” 拼接法 1 2 3 4 5 string str="a";   str+="c"+"d ...

  6. 使用位运算、值交换等方式反转java字符串-共四种方法

    在本文中,我们将向您展示几种在Java中将String类型的字符串字母倒序的几种方法. StringBuilder(str).reverse() char[]循环与值交换 byte循环与值交换 apa ...

  7. java 多线程实现四种方式解析Thread,Runnable,Callable,ServiceExcutor,Synchronized ,ReentrantLock

    1.Thread实现: import java.util.Date; import java.text.SimpleDateFormat; public class MyThread extends ...

  8. Java创建线程四种方式

    1.继承Thread类 public class MyThread extends Thread { public MyThread() { } public void run() { for(int ...

  9. java创建对象的四种方式

    1.最常见的 new 一个 2使用反射机制创建对象,直接调用非构造函数 Class obj=Class.forName("A"); A a=obj.newInstance(); C ...

随机推荐

  1. re正则匹配城市名

    匹配城市名称,只要第一次出现之后的数据 import re a='巴州区白云县台公交乡公司对面区海蜃楼6楼' b=re.search(r'(^\w+?区)|(^\w+?县)|(^\w+?镇)',a). ...

  2. vue2-通过axios实现数据请求

    1.通过axios实现数据请求 vue.js默认没有提供ajax功能 所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互. 注意,axios本质上就是javascr ...

  3. linux下tomcat启动慢解决方法

    前言 最近在工作中遇到一个问题,在Linux下Tomcat 8启动很慢,且日志上无任何错误,在日志中查看到如下信息: Log4j:[2017-08-2715:47:11] INFO ReadPrope ...

  4. 新安装mysql,如何提升mysql安全性

    1.修改mysql默认端口,将3306修改为其他端口. 2.设定足够复杂的密码策略并指定访问IP(在user表中可以指定用户可访问的访问IP地址). 3.设定IP访问白名单. 4.设定root用户只能 ...

  5. 华为PAY公交卡建议开卡免费!

    华为PAY公交卡,大家都知道是华为与当地交通卡通公司合作的,开卡费大概15-29元,最低充值10-30元. 估计大部分开卡费是给了当地交通卡公司,华为也应该有收入分成.这个虚拟公交卡,不同于实体公交卡 ...

  6. mac下常用命令

    常用命令 ls 查看当前目录下的文件 cd 进入某目录 . cd - 跳转回前一目录 . cd ~ 进入当前用户个人目录 pwd 输出当前所在路径 mkdir 新建文件夹. touch 新建文件 fi ...

  7. php中获取当前时间

    因为php种有时区的设置,默认与我们这边差8小时:所以我们直接使用data方法的话,得到的时间是不准确的 所以我们在开头设置时区 //设置时区的方法: date_default_timezone_se ...

  8. 发现一个非常有趣好用的git博主,收录热门OC、swift项目三方架构

    日常学习: https://github.com/iOShuyang/Book-Recommend-Github

  9. [UE4]抛物线指示器

    一.抛物线的有以下4中函数 二.本例使用Predict Projectile Path By TraceChannel方法. 抛物线三要素:发射位置.发射角度.发射速度. 1.Start Pos:起始 ...

  10. @property的使用

    1.可以将某个函数变为属性 class Name(): @property def name(self): print('xiaoming') Name().name这里name已经可以当做属性来调用 ...