滚雪球学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编程,就像滚雪球一样,越滚越大,指数级提升。

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

目录
相关文章
|
2月前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
83 14
|
1月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
25 1
|
2月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
65 8
|
2月前
|
安全
String、StringBuffer、StringBuilder的区别
String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。 StringBuffer可变并且线程安全;有一定缓冲区容量,字符串大小没超过容量,不会重新分配新的容量,适合多线程操作字符串; StringBuiler可变并且线程不安全。速度比StringBuffer更快,适合单线程操作字符串。 操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
|
2月前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
3月前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第12天】Java零基础教学篇,手把手实践教学!
42 5
|
3月前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
3月前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第11天】Java零基础教学篇,手把手实践教学!
48 1
|
3月前
|
存储 安全 Java
String、StringBuffer 和 StringBuilder 的区别
【10月更文挑战第21天】String、StringBuffer 和 StringBuilder 都有各自的特点和适用场景。了解它们之间的区别,可以帮助我们在编程中更合理地选择和使用这些类,从而提高程序的性能和质量。还可以结合具体的代码示例和实际应用场景,进一步深入分析它们的性能差异和使用技巧,使对它们的理解更加全面和深入。
61 0
|
5月前
|
安全 Java
【Java基础面试二十七】、说一说StringBuffer和StringBuilder有什么区别
这篇文章介绍了Java中StringBuffer和StringBuilder的区别:StringBuffer是线程安全的,而StringBuilder是非线程安全的,因此在单线程环境下优先推荐使用StringBuilder以获得更好的性能。