`
qindongliang1922
  • 浏览: 2188840 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117669
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126074
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:60034
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71402
社区版块
存档分类
最新评论

关于Java里面的字符串拼接,你了解多少?

    博客分类:
  • JAVA
阅读更多

# 关于Java里面的字符串拼接,你了解多少?

###  前言

字符串拼接是我们日常开发中很常见的操作,虽然常见,但要是使用不当的的话,很有可能让你的程序处理效率降低一大半,所以我们有必要来重新了解一下Java里面的字符串操作。


### 基础知识回顾
(1)关于字符串字面量

```
String text="我是攻城师1";
```

上面的这行代码是我们最常见的声明方式,它会创建一个对象,并放在字符串常量池里面,关于常量池的内容,可以参考我之前的文章。

(2)关于new String

```
String text2=new String("我是攻城师2")
```

上面的这段代码是通过new的方式来创建字符串对象的,这里总共会产生2个对象,第一个是new创建的在堆内存里,第二个是字面量创建的在常量池里面。此外text2变量是在线程的栈里面,它只引用了堆里面的对象实例,这一点需要注意很多新手分不清楚他们之间的联系。

(3)关于String不可变性
Java的里面String类的有关操作,都会生成新的String实例,所以在大量修改操作时,应该使用可变的StringBuffer或者StringBuilder。


### 字符串拼接的几种方法


(1)使用 + 号

(2)使用字符串的concat方法

(3)StringBuffer的append方法

(4)StringBuilder的append方法

上面的四种就是Java里面所有的关于字符串拼接的方法,问题来了四种方法之间有什么区别?


* StringBuffer是线程安全的,StringBuilder是线程不安全的,大部分时候应该首选StringBuilder方法,它的字符串拼接效率最高,因为不会创建很多的String实例。
* +号与concat方法的:
首先+号是可以和各种类型拼接字符串的,而concat的参数必须是字符串类型,其次concat方法拼接null值是会抛空指针的,代码如下:


```
//DIFFERENCE 1
	String a = null;
	String b = "foo";
	String c = a + b; // c = nullfoo

	String d = b.concat(a); // 空指针
	String e = a.concat(b); // 空指针
		
	//DIFFERENCE 2
	String x = "1" + 2; // x = 12
	String y = "1".concat(2); // 编译错误
```

最后,他们在底层处理机制上也不同:


```
String c ="a" + "b";
```

上面的语句在编译的时候会转化成下面的代码:

```
c = new StringBuilder()
		.append("a")
		.append("b")
		.toString();
```

注意上面的代码会涉及三次的new char[]数组分配和数组拷贝动作。

而同样的操作使用concat方法,则只会涉及一次的数组分组和数组拷贝:

```
String c=”a“.concat("b")
```

源码如下:

```
    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);
    }
```


### 字符串拼接的性能对比

下面我们分别对上面的四种方法在jdk8的mac系统上,进行1万次的拼接动作,看下性能表现,测试代码如下:


```
        final int loop_count=10000;

        // 1 +
        String s1="s1";
        long startTime=System.nanoTime();

        for (int i = 0; i < loop_count; i++) {
            s1=s1+Integer.toString(i);
        }
        long duration=System.nanoTime()-startTime;
        System.out.println(" + cost: "+duration/1000+" 微秒 ");



        // 2 concat
        String s2="s2";
        startTime=System.nanoTime();
        for (int i = 0; i < loop_count; i++) {
            s2=s2.concat(Integer.toString(i));
        }
        duration=System.nanoTime()-startTime;
        System.out.println(" concat cost: "+duration/1000+" 微秒 ");


        // 3 stringbuffer
        StringBuffer s3=new StringBuffer("s3");
        startTime=System.nanoTime();
        for (int i = 0; i < loop_count; i++) {
            s3.append(Integer.toString(i));
        }
        duration=System.nanoTime()-startTime;
        System.out.println(" StringBuffer cost: "+duration/1000+" 微秒 ");



        // 4 stringbuilder
        StringBuilder s4=new StringBuilder("s4");
        startTime=System.nanoTime();
        for (int i = 0; i < loop_count; i++) {
            s4.append(Integer.toString(i));
        }
        duration=System.nanoTime()-startTime;
        System.out.println(" StringBuilder cost: "+duration/1000+" 微秒 ");
```


结果输出如下:

```
 + cost: 432673 微秒 
 concat cost: 49118 微秒 
 StringBuffer cost: 1011 微秒 
 StringBuilder cost: 734 微秒
```


从上面的循环1万次拼接的结果来看+操作符在循环loop中拼接字符串最耗时,前两个结果与后两个结果完全不在一个量级上,因为前面的两种方法在每次循环时候都会生成一个新的String实例返回,而后面的两个则只需要最后使用一次,至于StringBuffer比StringBuilder耗时是因为前者是同步的方法,后者则不是。


### 总结

(1)在没有线程问题的情况下大量修改字符串优先考虑StringBuilder

(2)在有线程问题的情况下大量修改字符串优先考虑StringBuffer

(3)如果仅仅是两个字符串的拼接优先考虑String类的concat方法

(4)如果一次性拼接多个字符串,可以考虑使用非循环模式下的+号拼接
或者直接使用StringBuilder对象。

(5)最后还有一个不常用的方法String.join其内部用的是StringBuilder类,所以不再多说。




























0
0
分享到:
评论

相关推荐

    java 中根据html模板生成新的html

    总结来说,Java中根据HTML模板生成新的HTML涉及到对HTML模板的理解,选择合适的处理方式(如字符串拼接或使用模板引擎),以及熟悉相关的Java库和API。通过这样的方法,我们可以快速地生成动态的、个性化的HTML页面...

    华为-华为od题库练习题之字符串分隔.zip

    1. **字符串基本操作**:包括创建、赋值、长度计算、字符串拼接、比较等。 2. **字符串分割**:使用`split()`函数,可以按照指定的分隔符将字符串切割成多个子串,如Python中的用法。 3. **正则表达式分隔**:通过...

    java里面的 乘法列表 写法

    - `j + "*" + i + "=" + j * i`:拼接字符串,形成如“1*2=2”的格式。 - `\t`:表示一个制表符,用于对齐输出。 - `System.out.println()`: - 每次内层循环结束后执行该语句,用于换行,使输出结果呈现为标准的...

    java程序,书上的课后题,里面有题目和程序

    例如,在文件`XiTi1_1_1.java`中,通过双重嵌套的`for`循环实现了从1到9的乘法表打印,其中外层循环控制行数,内层循环控制列数,通过字符串拼接和条件判断来格式化输出结果。 ### 数组的定义与操作 数组是存储同...

    JAVA初级_JAVAsomething_java实验_源码.zip

    6. **字符串处理**:String类是Java中常用的一个类,源码中可能包含字符串的拼接、查找、替换等操作。 7. **函数式编程**:Java 8引入了Lambda表达式,使得函数式编程成为可能,源码中可能会有这方面的示例。 8. *...

    Util-源码.rar

    例如,"StringUtil.java"可能包含各种字符串操作的方法,如字符串拼接、格式化、分割等;"DateUtil.java"则可能提供了日期和时间的转换、计算等功能。 在深入分析之前,我们需要了解源码的基本结构和命名规范。通常...

    java 判断一个数组中的数值是否连续相邻的方法

    Java 判断数组中的数值是否连续相邻的方法 在 Java 编程语言中,判断一个数组中的数值是否连续相邻是一个常见的问题。今天,我们将分享一种简洁的方法来解决这个问题。 方法原理 该方法的主要思想是,遍历数组,...

    JDK-11.0.2_MacOS-x64_bin.dmg

    3. **文本块(Text Blocks)**: 提供多行字符串字面量,避免了转义字符和拼接字符串的繁琐。 4. **HTTP客户端API**: 内置的HTTP客户端库,简化网络通信。 5. **静态工厂方法代替构造函数**: 对于`Optional`、`...

    LeetCode-Java

    字符串问题在 LeetCode 中非常常见,涉及子串查找、拼接、替换等多种操作。 7. **递归与回溯**:这两种方法常用于解决复杂的问题,如搜索所有可能的解决方案或遍历树结构。理解和掌握递归原理至关重要。 8. **并发...

    freemarker总结

    有一种特殊的字符串称为raw字符串,被认为是纯文本,其中的\和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子: ${r"/${data}"year""}屏幕输出结果为:/${data}"year" 转义 含义 ...

    ibatiS架包

    Ibatis 是MyBatis的前身,它提供了一个SQL映射框架,可以将SQL语句编写在XML配置文件中,避免在Java代码中直接拼接SQL字符串,降低了SQL注入的风险。Ibatis的核心是SqlSession接口,它负责执行SQL、处理结果集以及...

    mybatis_plus插件2.7版本破解

    2. **条件构造器**:提供了一个强大的查询构造器,允许开发人员通过简单的API调用来构建复杂的SQL语句,避免了大量的字符串拼接,提高了代码的可读性和可维护性。 3. **动态SQL**:类似于MyBatis的动态XML标签,...

    Codeforces

    - 使用StringBuilder而非String进行字符串拼接,避免创建过多中间对象。 - 使用适当的数据结构和算法,遵循“早退原则”(尽早返回结果,避免不必要的计算)。 Codeforces-master这个文件名可能是该项目的源码...

    Coding.Bat

    3. **字符串处理**:Java的String类提供了丰富的字符串操作方法,如拼接、查找子串、替换、分割等。在Coding.Bat上,你将有机会实践这些操作。 4. **条件判断与逻辑运算**:包括if-else语句、switch语句以及逻辑...

    leetcode答案-LeetCode:力码

    5. **字符串处理**:字符串操作在编程中非常常见,LeetCode的题目可能涉及到字符串拼接、模式匹配、子串查找、字符计数等。 6. **数学应用**:一些题目需要运用到基础数学知识,比如组合数学、概率论、数论等。 7....

    Codility:Codility 课程的解决方案

    3. **字符串处理**:字符串的拼接、分割、查找子串、模式匹配等。 4. **递归**:在解决一些复杂问题时,如斐波那契数列、树的遍历等,递归是常用的方法。 5. **排序和搜索算法**:快速排序、归并排序、二分查找等...

    python学习项目1

    2. **字符串操作**:Python的字符串是不可变的,但提供了丰富的操作方法,如切片、拼接、查找、替换、分割等。 3. **列表和元组**:列表是可变的有序集合,元组则是不可变的有序集合。它们都可以通过索引访问,支持...

    MATLAB 语言程序设计基础 课件

    2. **基本数据类型与结构**:讲解MATLAB中的基本数据类型,如标量、向量、矩阵和数组,以及复数、逻辑值和字符串。还会涉及结构体和细胞数组,这些复杂数据类型用于存储不同类型的数据。 3. **运算符与表达式**:...

    uri-online-solutions::package:装有URI Online解决方案的盒子,按类别和语言划分,请享用https

    1. **基础语法**:包括变量声明(var、let、const)、数据类型(字符串、数字、布尔值、对象、数组等)、条件语句(if...else、switch)、循环(for、while、do...while)等。 2. **函数**:函数的定义、参数传递、...

    oolongtea-matlab.zip

    2. **语法与数据类型**:MATLAB支持多种数据类型,包括标量、向量、矩阵、数组、字符串等。理解这些数据类型的创建、操作和转换是学习MATLAB的基础。 3. **函数与脚本**:MATLAB允许用户定义自己的函数,通常以.m...

Global site tag (gtag.js) - Google Analytics