`

java 字符串相加

    博客分类:
  • java
阅读更多
字符串相加。string + (原作者: 火龙果)

为了加深理解,我们可以来做几个小实验。

javac Test 编译文件
javap -c Test 查看虚拟机指令

实验一:纯字符串
Java code
public class Test {
    public static void main(String args[]) {
        String str = "a";
    }
}



  // 将字符串 a 存入常数池
  0: ldc #2; //String a
  // 将引用存放到 1 号局部变量中
  2: astore_1
  3: return

实验二:纯字符串相加
Java code
public class Test {
    public static void main(String args[]) {
        String str = "a" + "b";
    }
}



  // 将字符串 ab 压入常数池
  0: ldc #2; //String ab
  2: astore_1
  3: return

实验二可以很明显地看出,编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab",
同理多个字符串的相加也会被优化处理,需要注意的是字符串常量相加。

实验三:字符串与自动提升常量相加
Java code
public class Test {
    public static void main(String args[]) {
        String str = "a" + (1 + 2);
    }
}



  // 将字符串 a3 压入常数池
  0: ldc #2; //String a3
  2: astore_1
  3: return

通过虚拟机指令可以看出,1 + 2 自动提升后的常量与字符串常量,虚拟机也会对其进行优化。

实验二、实验三结论:常量间的相加并不会引起效率问题

实验四:字符串与变量相加
Java code
public class Test {
    public static void main(String args[]) {
        String s = "b";
        String str = "a" + s;
    }
}



  // 将字符串 b 压入常数池
  0: ldc #2; //String b
  // 将引用存放到 1 号局部变量中
  2: astore_1
  // 检查到非常量的相加,这时创建 StringBuilder 对象
  3: new #3; //class java/lang/StringBuilder
  // 从栈中复制出数据,即把字符串 b 复制出来      //b 不是在常数池里面吗,这里的栈是指常数池了的栈吗? 还有复制出来,指的是复制到哪里??
  6: dup
  // 调用 StringBuilder 的初始构造
  7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
  // 将字符串 a 压入常数池
  10: ldc #5; //String a
  // 调用 StringBuilder 的 append 方法,把字符串 a 添加进去
  12: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  // 从 1 号局部变量中加载数据引用
  15: aload_1
  // 调用 StringBuilder 的 append 方法,把字符串 b 添加进去
  16: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  // 调用 StringBuilder 的 toString 方法
  19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  // 将 toString 的结果保存至 2 号局部变量
  22: astore_2
  23: return

实验四可以看出,非常量字会串相加时,由于相加的变量中存放的是字符串的地址引用,
因为在编译时无法确切地知道其他具体的值,也就没有办法对其进行优化处理,这时为了
达到连接的效果,其内部采用了 StringBuilder 的机制进行处理(JDK 5 中新增的,我
这里没有 JDK 1.4,估计在 JDK 1.4 下采用的是 StringBuffer),将他们都 append
进去,最后用 toString 输出。

若 s 为其他类型时,比如:int 类型,也是采用同种方式进行处理。

同理,根据实验二的结果,在 String str = "a" + "b" + s; 时,先会优化成 "ab" 再与
s 根据实验四的方式进行处理,这时 StringBuilder 仅调用了两次 append 方法。

如果是 String str = "a" + s + "b"; 这种形式的就没办法优化了,StringBuilder 得调
用三次 append 方法。

实验四的结论表明,字符串与变量相加时在内部产生了 StringBuilder 对象并采取了一定
的操作。

如果只有一句 String str = "a" + s; 这样子的,其效率与
String str = new StringBuilder().append("a").append(s).toString();
是一样的。

一般所说的 String 采用连接运算符(+)效率低下主要产生在以下的情况中:

Java code
public class Test {
    public static void main(String args[]) {
        String s = null;
        for(int i = 0; i < 100; i++) {
            s += "a";
        }
    }
}



每做一次 + 就产生个 StringBuilder 对象,然后 append 后就扔掉。下次循环再到达时重
新产生个 StringBuilder 对象,然后 append 字符串,如此循环直至结束。

如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和
销毁对象的时间。
分享到:
评论

相关推荐

    Java字符串前面或后面补0(适用于等不同长度比较) .txt

    Java字符串长度不够,将其前面补0或者后面补0,适用于字典序比较前,将要比较字符串的位数保持一致,再进行比较。

    java-leetcode题解之第415题字符串相加.zip

    在本压缩包“java-leetcode题解之第415题字符串相加.zip”中,包含的是关于LeetCode第415题“字符串相加”(Add Strings)的Java解决方案。这道题目属于计算机编程领域,特别是Java语言的学习与算法实践。LeetCode是...

    java字符串连接效率测试代码

    用于测试java字符串几种连接方式的效率,主要包括四类对比测试:1,StringBuffer连接,2,String的Format连接,3,String相加连接,4,StringBuffer的append串起来连接。测试结果如下: String Buffer: 580ms String...

    Java 程序将两个二进制字符串相加.docx

    在Java编程中,将两个二进制字符串相加是一个常见的任务,这通常涉及到将字符串转换为整数,进行加法运算,然后将结果转换回二进制字符串。下面我们将详细探讨两种实现方法。 方法一: 这种方法是通过首先将二进制...

    BinaryStringCalculator:两个二进制字符串相加的算法

    本文将深入探讨如何实现一个二进制字符串计算器,以完成将两个二进制字符串相加的任务。我们将主要关注Java编程语言,因为这是给定的标签。 首先,我们需要了解二进制字符串的基本概念。二进制是计算机内部处理数据...

    java 倒置字符串

    在Java编程语言中,倒置字符串是一个常见的任务,它涉及到将一个给定的字符串的字符顺序反转。在本文中,我们将深入探讨如何在Java中实现这个功能,...同时,了解这些不同的实现方式有助于加深对Java字符串操作的理解。

    TanaStudy#Java-Study#Q415字符串相加1

    示例 1:输出:"134"示例 2:输出:"533"示例 3:输出:"0"提示:num1 和num2 都只包含数字 0-9num1 和num2 都不包含任何前导

    数字类型的转换、字符串类型1

    本节主要探讨的是Python中的数字类型转换以及与字符串类型的交互。 首先,Python支持三种基本的数字类型:整数(int)、浮点数(float)和布尔型(bool)。布尔型实际上可以被视为整数的子类型,其中`True`相当于`1...

    java实验一 图形 字符串 复数

    ### Java 实验知识点详解 #### 一、设计图形软件包 根据题目要求,我们需要设计一个图形软件包,其中包含三个类:三角形类、...此外,还涉及了字符串处理和数组操作的基础知识,这些都是Java编程的重要组成部分。

    java基本语法—字符串与数值型数据转换、从键盘输入数据

    Java 基本语法—字符串与数值型数据转换、从键盘输入数据 本实验报告主要讲述了 Java 基本语法中字符串与数值型数据转换、从键盘输入数据的相关知识点。下面是本实验报告的详细内容: 一、实验目的 在本实验中,...

    JAVA中字符串如何与整型数字相加

    JAVA中字符串与整型数字相加 在 Java 编程语言中,字符串与整型数字相加是一种常见的操作。然而,对于初学者而言,如何正确地将字符串与整型数字相加却是一个难题。本文将详细介绍 Java 中字符串与整型数字相加的...

    md5加密实现对字符串进行简单加密

    MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,它能够将任意长度的输入数据转换为固定长度的输出,通常是32位的十六进制字符串。在IT行业中,MD5主要用于数据完整性校验和简单的密码加密。 MD5算法...

    java执行字符串公式.docx

    2. **add 方法**:此方法实现了两个字符串表示的数字相加。首先调用 `null2zero` 方法处理输入,然后创建两个 `BigDecimal` 对象并使用 `add` 方法计算它们的和,最后返回结果的字符串表示。 3. **add2 方法**:这...

    计算器(输入字符串解析运算)

    例如,输入字符串"2 + 3 * 4"需要被解析为两个操作:首先计算括号内的3 * 4,然后将结果与2相加。解析器通常使用**词法分析**(lexing)和**语法分析**(parsing)来完成这项工作。词法分析将输入分解成一个个称为...

    Java字符拼接成字符串的注意点详解

    Java字符拼接成字符串的注意点详解 在Java中,字符拼接成字符串是一个常见的操作,但是很多开发者并不知道在拼接字符时的一些注意点。今天,我们将详细介绍Java字符拼接成字符串的注意点详解。 1. 字符与ASCII码的...

    字符串实现大数字的相乘相加以及求指数

    当数字大到不能用long来表示的时候,我们可以用String来表示,这样相乘相加不受位数限制,同时可以用于求大指数,例如pow(2,1000)

    JAVA字符串类型switch的底层原理详析

    JAVA字符串类型switch的底层原理详析 JAVA字符串类型switch的底层原理详析是指在JAVA语言中,switch语句是如何处理字符串类型的表达式的。从表面上看,switch语句似乎可以直接处理字符串类型的表达式,但是实际上,...

    将长整型转换为字符串的Java程序.docx

    这是最简单的方法,只需将 Long 变量与空字符串 "+" 相加,即可完成转换。例如: ```java String str = varLong + " "; ``` 这会导致自动装箱(Long 转成 Long 对象)并调用 Long 的 toString() 方法,然后通过拼接...

    Java中string字符串和char字符之间的千丝万缕

    符之间的拼接字符之间的拼接在Java中,String与char之间的拼接主要涉及到字符串与单个字符的相互转换。以下是一些示例: 1. String字符串转换为char字符: - 如果想要将一个String字符串中的单个字符提取出来,...

Global site tag (gtag.js) - Google Analytics