String,StringBuffer,StringBuilder

简介: String,StringBuffer,StringBuilder 这三者的区别是 Java 学习中的一个基础知识,也是在面试中经常会问到的一个知识点StringString 也许是 ...

String,StringBuffer,StringBuilder 这三者的区别是 Java 学习中的一个基础知识,也是在面试中经常会问到的一个知识点

String

String 也许是 Java 中最常被用到的类了,关于它,有很多值得一提的地方

首先,Java 中的 String 是一个 char 类型序列:

char[] data = {'a', 'b', 'c'};

// 等价于

String str = "abc";

不过,更加严格地定义 String , 它应该是 Unicode 字符序列(char 数据类型就是一个采用 UTF-16 编码表示 Unicode 码点的代码单元)
关于 Unicode 字符我们需要知道,大多数常用的 Unicode 字符使用一个代码单元就可以表示,而一些特殊字符则需要两个代码单元

关于 String 我们一定要记住的最重要的特性是,String 是不可变的常量
当你 new 一个 String 对象以后,它的值就确定了,不能做修改,String 类中也没有提供可供修改其内容的方法。这样做的主要目的是为了实现 字符串共享 从而提高效率
在详细讲述这点前,我们需要注意一点:你也许会把 String 想象成一个 char 数组(char[]),这种认识是错误的,String 应该类似于是一个 char 指针(char*)

我们来做一下验证:

public class Test {
    public static void main(String[] args) {
        String str_1 = "hello";
        String str_2 = "hello";

        System.out.println("地址相同?" + (str_1 == str_2));
        System.out.println("内容相同?" + str_1.equals(str_2));
    }
}

如果说“==”是用来比较地址的,这个说法不够严格,其实“==”就是比较内容的,因为 String 变量是一个引用,它的存储的内容就是对象的内存地址。而 equals() 方法是用来比较对象内的数据内容的。
上面代码的输出结果是:
这里写图片描述
可以看到,str_1 和 str_2 引用着同一个数据,它们共享一个“hello”

如果我们修改一下代码:

public class Test {
    public static void main(String[] args) {
        String str_1 = "hello";
        String str_2 = new String("hello"); // new 出一个 str_2

        System.out.println("地址相同?" + (str_1 == str_2));
        System.out.println("内容相同?" + str_1.equals(str_2));
    }
}

这次的结果是:
这里写图片描述
这次就指向了不同的数据(但是内容相同)

在这里你也许还会有一个疑问:如果 String 不可变,每次需要一个新的 String 时就要重新 new 一个出来,那么不是很浪费空间?
没有关系,这个工作只需要交给 Java 的自动垃圾回收机制(GC)去做,你不用担心

通过上面的讲述,我们还可以看出一个 String 的特性,那就是 可以直接使用 “+”拼接字符串,当然不仅可以字符串之间拼接,当其他类型的数据和字符串之间用 “+”连接就会自动转化为字符串类型


StringBuffer

前面我们说过了,String 不可变,每 new 一个新 String 出来后,旧 String 的回收交给 JVM 去做,这样一来,虽然我们不用担心内存溢出的问题,但是这无疑增加了工作量,会极大的降低性能,因此我们有了 StringBuffer

我们可以把 StringBuffer 看做是一个 可修改的 String
而且 StringBuffer 是线程安全的,也就是说它适用于多线程的环境下,在任意时刻,只能有一个线程对 StringBuffer 进行操作,它的每一个方法都被 synchronized 所修饰

StringBuffer 中最主要的两个方法是 append 和 insert

//append 方法用于将修改的字符串添至原字符串末尾
StringBuffer str = new StringBuffer("hello");
str.append("abc");
System.out.println(str);

//结果:helloabc
//insert 方法用于将修改的字符串添加至指定的位置
StringBuffer str = new StringBuffer("hello");
str.insert(3, "abc");
System.out.println(str);

//结果:helabclo


StringBuilder

StringBuilder 是在 JDK 5 中新加入的,它可以看做是 StringBuffer 的单线程版本,它与 StringBuffer 唯一的区别就是取消了线程同步机制

因为 StringBuilder 没有线程同步机制,所以 StringBuilder 的性能要优于 StringBuffer

因此,如果不是在多线程操作字符串的情况下,尽量使用 StringBuilder

其实 StringBuffer 是一个极少被用到的类,因为几乎不会存在多线程修改字符串的情况

目录
相关文章
|
3月前
|
安全 Java API
【Java字符串操作秘籍】StringBuffer与StringBuilder的终极对决!
【8月更文挑战第25天】在Java中处理字符串时,经常需要修改字符串,但由于`String`对象的不可变性,频繁修改会导致内存浪费和性能下降。为此,Java提供了`StringBuffer`和`StringBuilder`两个类来操作可变字符串序列。`StringBuffer`是线程安全的,适用于多线程环境,但性能略低;`StringBuilder`非线程安全,但在单线程环境中性能更优。两者基本用法相似,通过`append`等方法构建和修改字符串。
65 1
|
6天前
|
安全
String、StringBuffer、StringBuilder的区别
String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。 StringBuffer可变并且线程安全;有一定缓冲区容量,字符串大小没超过容量,不会重新分配新的容量,适合多线程操作字符串; StringBuiler可变并且线程不安全。速度比StringBuffer更快,适合单线程操作字符串。 操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
|
2月前
|
安全 Java
String、StringBuffer、StringBuilder的区别
这篇文章讨论了Java中String、StringBuffer和StringBuilder的区别。String是不可变的,每次操作都会产生新的对象,效率低且浪费内存。StringBuilder可以在原字符串基础上进行操作,不开辟额外内存,弥补了String的缺陷。StringBuffer和StringBuilder类似,但StringBuffer的方法是线程安全的。文章还列举了StringBuffer的常用方法,并提供了使用示例代码。最后总结了这三者的主要区别。
String、StringBuffer、StringBuilder的区别
|
1月前
|
canal 安全 索引
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
37 5
|
28天前
|
存储 安全 Java
String、StringBuffer 和 StringBuilder 的区别
【10月更文挑战第21天】String、StringBuffer 和 StringBuilder 都有各自的特点和适用场景。了解它们之间的区别,可以帮助我们在编程中更合理地选择和使用这些类,从而提高程序的性能和质量。还可以结合具体的代码示例和实际应用场景,进一步深入分析它们的性能差异和使用技巧,使对它们的理解更加全面和深入。
17 0
|
2月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类详解
在 Java 中,`StringBuffer` 和 `StringBuilder` 用于操作可变字符串,支持拼接、插入、删除等功能。两者的主要区别在于线程安全性和性能:`StringBuffer` 线程安全但较慢,适用于多线程环境;`StringBuilder` 非线程安全但更快,适合单线程环境。选择合适的类取决于具体的应用场景和性能需求。通常,在不需要线程安全的情况下,推荐使用 `StringBuilder` 以获得更好的性能。
|
3月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
152 0
|
2月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
39 0
java基础(13)String类
|
1月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
57 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
1月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
28 2
下一篇
无影云桌面