详述 Java 语言中的 String、StringBuffer 和 StringBuilder 的使用方法及区别

1 简介

在 Java 语言中,共有 8 个基本的数据类型,分别为:byteshortintlongfloatdoublebooleanchar,其中char类型用于表示单个字符,例如 a、b、c 、A、B、C、& 这些大小写字母或者特殊字符等等。在实际的编程中,单个的字符并没有我们想象中用的那么频繁,反而是多个字符组成的“字符串”更为常见,但是在基本的数据类型中,并没有字符串这种数据类型。为了解决这个问题,Java 语言为我们提供了一个被final关键字修饰的类 String,她就表示字符串类型,同时由于其被final修饰,这也表明咱们只能用这个类创建字符串以及调用其中的方法,却不能继承她。

虽然 Java 语言为我们提供了字符串类 String,能让我们方便的使用字符串类型,姑且这么说,但是在不断的发展中,我们发现单纯的 String 类型,并不足以满足我们的需求啦!因此,在 String 类型的基础上,又衍生出了两个字符串构建器 StringBuffer 和 StringBuilder。对于这三种类型,无论是在求职面试的过程中,还是在日后的实际工作中,都是需要我们经常面对的,因此了解她们之间的区别就显得尤为重要啦!

2 String

通过阅读“1 简介”,我们已经大致了解了 String 类型啦!说她是一个数据类型,但她并不是基本数据类型,而是一个被final修饰的、不可被继承的类,位于java.lang包。至于如何使用 String 类型,有两种方法,一是直接赋值,二是用new创建,具体示例如下:

// 1、直接赋值
String str1 = "维C果糖";

// 2、用 new 运算符创建
String str2 = new String("维C果糖");

在常见的字符串操作中,判断两个字符串是否相等尤为常见,且常用的判别方式有两种,即用 String 类提供的方法equals==运算符,在博文「Java 语言中 equals 和 == 的区别」中,作者详述了两者的区别,有兴趣的童鞋可以参考参考。接下来,我们介绍一些使用频率比较高的 String 类的 API 方法:

/* 如果字符串以 suffix 结尾,则返回 true,否则返回 false */
boolean endsWith(String suffix)

/* 如果字符串与 other 相等,则返回 true,否则返回 false */
boolean equals(Object other)

/* 如果字符串与 other 相等(忽略大小写),则返回 true,否则返回 false */
boolean equalsIgnoreCase(String other)

/* 返回字符串的长度 */
int length()

/* 返回一个新字符串,这个字符串用 newString 字符串代替原始字符串中所以的 oldString 字符串,可以用 String 或者 StringBuilder 对象作为 CharSequence 参数 */
String replace(CharSequence oldString, CharSequence newString)

/* 如果字符串以 prefix 开始,则返回 true,否则返回 false */
boolean startsWith(String prefix)

/* 返回一个新字符串,这个字符串包含原始字符串中从 beginIndex 到串尾或 endIndex-1 位置的所以代码单元 */
String substring(int beginIndex)
String substring(int beginIndex, int endIndex)

/* 返回一个新字符串,这个字符串将原始字符串中的所以大写字母都改成了小写字母 */
String toLowerCase()

/* 返回一个新字符串,这个字符串将原始字符串中的所以小写字母都改成了大写字母 */
String toUpperCase()

/* 返回一个新字符串,这个字符串将删除元字符串头部和尾部的空格 */
String trim()

3 StringBuffer

在我们了解了 String 类之后,我们会发现她有些缺陷,例如当我们创建了一个 String 类的对象之后,我们很难对她进行增、删、改的操作,为了解决这个弊端,Java 语言就引入了 StringBuffer 类。StringBuffer 和 String 类似,只是由于 StringBuffer 的内部实现方式和 String 不同,StringBuffer 在进行字符串处理时,不用生成新的对象,所以在内存的使用上 StringBuffer 要优于 String 类。

在 StringBuffer 类中存在很多和 String 类一样的方法,这些方法在功能上和 String 类中的功能是完全一样的。但是有一个非常显著的区别在于,StringBuffer 对象每次修改都是修改对象本身,这点是其和 String 类的最大区别。

此外,StringBuffer 是线程安全的,可用于多线程。而且 StringBuffer 对象的初始化与 String 对象的初始化不大一样,通常情况下,我们使用构造方法进行初始化,即:

// 声明一个空的 StringBuffer 对象
StringBuffer sb = new StringBuffer();

// 声明并初始化 StringBuffer 对象
StringBuffer sb = new StringBuffer("维C果糖");

// 下面的赋值语句是错的,因为 StringBuffer 和 String 是不同的类型
StringBuffer sb = "维C果糖";

// 下面的赋值语句也是错的,因为 StringBuffer 和 String 没有继承关系
StringBuffer sb = (StringBuffer)"维C果糖";

// 将 StringBuffer 对象转化为 String 对象
StringBuffer sb = new StringBuffer("维C果糖");
String str = sb.toString();

接下来,介绍一些 StringBuffer 常用的 API 方法:

/* 构造一个空的字符串构建器 */
StringBuffer()

/* 返回构建器或缓冲器中的代码单元(字符)数量 */
int length()

/* 追加一个字符串并返回一个 this */
StringBuffer append(String str)

/* 追加一个字符并返回一个 this */
StringBuffer append(Char c)

/* 将第 i 个代码单元设置为 c */
void setCharAt(int i, char c)

/* 将构建器的内容进行顺序的反转 c */
StringBuffer reverse()

/* 返回一个与构建器或缓冲器内容相同的字符串 */
String toString()

4 StringBuilder

在 JDK 5.0 之后,Java 语言又引入了 StringBuilder 类,这个类的前身是 StringBuffer,其效率略微有些低,但允许采用多线程的方式执行添加或者删除字符的操作。如果所有的字符串在一个单线程中(通常都是这样)编辑,则应该用 StringBuilder 代替她,这两个类的 API 是完全相同的。因此,在本部分,我们就不再赘言啦!

5 总结

通过以上的介绍,我们已经详细的了解了 String、StringBuffer 和 StringBuilder,也知道了她们三个都是用于操作字符串的类。接下来,大致总结一些三者的区别,以供参考:

  1. 对于操作效率而言,一般来说,StringBuilder > StringBuffer > String;
  2. 对于线程安全而言,StringBuffer 是线程安全的,可用于多线程;而 StringBuilder 是非线程安全的,用于单线程;
  3. 对于频繁的字符串操作而言,无论是 StringBuffer 还是 StringBuilder,都优于 String。

此外,通过 String 创建的对象的是不可变的,而通过 StringBuffer 和 StringBuilder 创建的对象是可以变的,这里的变与不变,指的是字符串的内容和长度。如果为了应对面试,能够记住以上内容的话,我想足够答的 perfect 啦;但是在实际开发中如何选择,则要具体情况具体分析啦!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

06 - JavaSE之常用类

public StringBuffer append(...) 可以为该 StringBuffer 对象添加字符序列,返回添加后的该 StringBuffer ...

752
来自专栏老马说编程

(89) 正则表达式 (中) / 计算机程序的思维逻辑

上节介绍了正则表达式的语法,本节介绍相关的Java API。 正则表达式相关的类位于包java.util.regex下,有两个主要的类,一个是Pattern,另...

1967
来自专栏武培轩的专栏

剑指Offer-栈的压入、弹出序列

题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压...

3427
来自专栏无题

链式存储线性表(LinkedList)数据结构解析

LinkedList内部是通过链表来实现的 一、节点分析 LinkedList内部是通过链表来实现的,那么就少不了节点,所以在源码中必然能找到这样一个节点。 ...

3326
来自专栏PHP实战技术

PHP使用栈完成高级计算器-接上文模拟栈

距离上一篇文章PHP模拟栈,小梦就答应了小伙伴们要使用栈来完成一个实战的例子,今天就给大家带来了这个例子,让大家更加深入理解它的使用场景!

681
来自专栏海说

Java源码学习 -- java.lang.String

java.lang.String是使用频率非常高的类。要想更好的使用java.lang.String类,了解其源代码实现是非常有必要的。由java.lang.S...

2100
来自专栏赵俊的Java专栏

合并排序数组 Ⅱ

1624
来自专栏Java帮帮-微信公众号-技术文章全总结

13(01)总结StringBuffer,StringBuilder,数组高级,Arrays,Integer,Character

1:StringBuffer(掌握) (1)用字符串做拼接,比较耗时并且也耗内存,而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了 一...

4205
来自专栏微信公众号:Java团长

Java正则表达式入门

1.定义:正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查...

1002
来自专栏C/C++基础

C++抛出异常与传递参数的区别

C++的异常处理机制有3部分组成:try(检查),throw(抛出),catch(捕获)。把需要检查的语句放在try模块中,检查语句发生错误,throw抛出异常...

993

扫码关注云+社区

领取腾讯云代金券