滚雪球学Java(50):理解Java中String、StringBuilder和StringBuffer的区别与选择

简介: 【6月更文挑战第4天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

在这里插入图片描述

  咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~


🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

@[toc]

前言

  在Java中,字符串是最常见的数据类型之一。在日常编程中,我们经常需要连接、修改或比较字符串。Java提供了三种不同的类来处理字符串:String、StringBuilder和StringBuffer。虽然它们都可以用来表示字符串,但它们之间有着很大的区别和不同的使用场景。在这篇文章中,我们将深入了解这三种类,以便在实际开发中做出正确的选择。

摘要

  本文将介绍Java中的三种字符串类:String、StringBuilder和StringBuffer。我们将分别介绍它们的性能和使用场景,并且提供示例代码和测试用例。最后,我们将作出总结,以便您在实际开发中做出正确的选择。

正文

String类

  String类是Java中最基本的字符串类。它是不可变的,即一旦字符串被创建,就不能被修改。当我们尝试修改它时,实际上是在创建一个新的字符串对象。这意味着,在对字符串进行频繁的操作时,String类的效率很低。

示例代码:

String s1 = "hello";
String s2 = s1 + "world";

  在上面的代码中,我们使用了“+”运算符来连接两个字符串。这将创建一个新的字符串对象,其中包含“hello”和“world”两个字符串。

StringBuilder类

  StringBuilder类是Java中用于处理可变字符串的类。它提供了一个可变的字符序列,可以进行添加、删除和修改等操作。与String类不同的是,StringBuilder类是可变的,这意味着我们可以对同一个对象进行多次修改而不需要创建新的对象。因此,它的效率比String类高。

示例代码:

StringBuilder sb = new StringBuilder("hello");
sb.append("world");

  在上面的代码中,我们使用了StringBuilder的append()方法,将“world”添加到了字符串后面,而不会创建新的对象。

StringBuffer类

  StringBuffer类与StringBuilder类功能类似,也是Java中用于处理可变字符串的类。区别在于,StringBuffer类是线程安全的。这意味着在多线程环境中使用StringBuffer时,我们不需要担心并发问题。但是,它的效率比StringBuilder类低。

示例代码:

StringBuffer sb = new StringBuffer("hello");
sb.append("world");

  在上面的代码中,我们使用了StringBuffer的append()方法,将“world”添加到了字符串后面,而不会创建新的对象。

示例演示

  借此针对三类进行基本的使用以作为开篇介绍,如果需要对单独某个类有深入的了解,可以参考如下三篇:

如下是示例代码的全部代码,演示了String、StringBuilder和StringBuffer的用法,同学们可以再温习一遍。

package com.demo.javase.day50;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 11:17
 */
public class StringDemo {
   
   

    public static void main(String[] args) {
   
   
        String s = "hello";
        s = s + "world"; // 新对象
        System.out.println(s);

        StringBuilder sb = new StringBuilder("hello");
        sb.append("world"); // 相同对象
        System.out.println(sb.toString());

        StringBuffer sbf = new StringBuffer("hello");
        sbf.append("world"); // 相同对象
        System.out.println(sbf.toString());
    }
}

上述代码执行结果如下:

在这里插入图片描述

性能比较

  在实际开发中,我们需要根据需求选择不同的字符串类。下面是三种类的性能比较:

类型 是否可变 线程安全 效率
String 不可变 N/A
StringBuilder 可变 不安全
StringBuffer 可变 安全

  可以看出,如果我们需要对字符串进行频繁的操作,则应该使用StringBuilder类。如果我们在多线程环境中使用字符串,则应该使用StringBuffer类。

性能测试示例

为了验证性能比较的结果,我们编写了以下测试用例,对比10 万次字符串连接各自需要耗时多久。

package com.demo.javase.day50;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 14:33
 */
public class StringPerformanceTest {
   
   

    private static final int ITERATIONS = 100000;
    private static final String STR_TO_APPEND = "hello";

    public static void main(String[] args) {
   
   
        String string = "hello";

        long start = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
   
   
            string = string + STR_TO_APPEND;
        }
        long end = System.currentTimeMillis();
        System.out.println("String time耗时: " + (end - start) + "ms");

        StringBuilder stringBuilder = new StringBuilder("hello");
        start = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
   
   
            stringBuilder.append(STR_TO_APPEND);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder time耗时: " + (end - start) + "ms");

        StringBuffer stringBuffer = new StringBuffer("hello");
        start = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
   
   
            stringBuffer.append(STR_TO_APPEND);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer time耗时: " + (end - start) + "ms");
    }
}

测试结果展示

如上代码执行需要耗费点时间,测试执行的小伙伴需耐心等待。

如不想等待的同学可直接参考如下执行结果:

在这里插入图片描述

测试代码分析

  这段代码测试了使用字符串拼接、StringBuilder、StringBuffer 三种方式进行字符串连接的性能差异。代码的核心是分别测试,在进行 10 万次字符串连接时,使用不同的方式所需时间的差异。其中,String 表示使用 Java 中的字符串拼接方式,StringBuilder 表示使用 StringBuilder 进行字符串连接,StringBuffer 表示使用 StringBuffer 进行字符串连接,三种方式的输出都包含所需时间的信息。

测试结论

  在 Java 中,String 对象是不可变的,每当对 String 对象进行改变时,都会创建一个新的 String 对象。因此,每次使用字符串拼接时,实际上都会创建新的 String 对象,这在循环中进行数万次会比较慢,因此性能较差。

  相比之下,StringBuilder 和 StringBuffer 通过修改其内部缓冲区来实现字符串的连接,不会在循环中创建新的对象,能够提高性能。其中,StringBuilder 是线程不安全的,但速度更快;而StringBuffer 是线程安全的,但速度相对较慢。

  因此,使用 StringBuilder 进行字符串连接是更好的选择,能够获得更好的性能表现。

小结

  在Java中,我们可以使用String、StringBuilder和StringBuffer处理字符串。String类是不可变的,每次操作都会创建新的对象,效率较低。StringBuilder类是可变的,可以对同一个对象进行多次操作,效率较高。StringBuffer类也是可变的,但是线程安全,适用于多线程环境。在实际开发中,我们需要根据需求选择不同类型的字符串类。为了获得更好的性能,我们应该尽可能使用StringBuilder类。

附录源码

  如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

总结

  在Java中,字符串是最常见的数据类型之一。理解String、StringBuilder和StringBuffer的区别和选择非常重要。本文介绍了三种类的性能和使用场景,并提供了示例代码和测试用例。希望您能在实际开发中做出正确的选择。

☀️建议/推荐你


  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

目录
相关文章
|
16天前
|
Java
Java中String的用法
Java中String的用法
|
3天前
|
Java
Java编程不再难:一文看懂抽象类与接口的区别和联系!
【6月更文挑战第17天】在Java OOP中,抽象类与接口助你构建复杂应用。以图书管理系统为例,抽象类`Book`作为基类提供共享属性和方法,不直接实例化。接口如`HasChapters`和`HasIssues`定义特殊行为。抽象类支持部分实现,单继承,适合共享行为;接口仅含常量和抽象方法,多实现,强调行为规范。通过继承和实现,实现代码复用和系统扩展性。理解两者异同,是提升Java编程能力的关键。
|
7天前
|
Java C++
Java和C++的一些区别
Java和C++的一些区别
|
7天前
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
4 0
|
8天前
|
Java
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(二)
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(二)
11 0
|
8天前
|
设计模式 Java 内存技术
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(一)
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(一)
14 0
|
8天前
|
安全 Java 数据安全/隐私保护
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
15 0
|
8天前
|
JSON 安全 Java
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(一)
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(一)
19 0
|
8天前
|
Java
guava Splitter 与java 内置的string的split 方法的区别
guava Splitter 与java 内置的string的split 方法的区别
8 0
|
10天前
|
Java
Java中判断String类型为空和null的方法
Java中判断`String`变量是否为空或`null`需用`== null`和`.isEmpty()`。示例代码提供两种方法:`main`方法直接判断,`safeGetString`方法提供默认值。当输入为`null`或空时,返回默认值。代码包含三个测试案例,分别处理`null`、空字符串和非空非`null`字符串。
30 0