当前位置:首页>Java>Java教程>Java StringBuffer 和 StringBuilder 类

Java StringBuffer 和 StringBuilder 类

作者:微学网发布时间:2019-09-13 16:17:13

Java StringBuffer 和 StringBuilder 类 简介

当对字符串进行修改的时候,需要使用 StringBufferStringBuilder 类。

和 String 类不同的是,StringBufferStringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

Test.java 文件代码:

public class Test{
  public static void main(String args[]){
    StringBuffer sBuffer = new StringBuffer("微学网官网:");
    sBuffer.append("www");
    sBuffer.append(".weixue");
    sBuffer.append(".wang");
    System.out.println(sBuffer);  
  }
}

以上示例编译运行结果如下:

微学网官网:www.weixue.wang

StringBuffer 方法

以下是 StringBuffer 类支持的主要方法:

序号 方法描述
1 public StringBuffer append(String s)将指定的字符串追加到此字符序列。
2 public StringBuffer reverse() 将此字符序列用其反转形式取代。
3 public delete(int start, int end)移除此序列的子字符串中的字符。
4 public insert(int offset, int i)将 int 参数的字符串表示形式插入此序列中。
5 replace(int start, int end, String str)使用给定 String 中的字符替换此序列的子字符串中的字符。

下面的列表里的方法和 String 类的方法类似:

序号 方法描述
1 int capacity()返回当前容量。
2 char charAt(int index)返回此序列中指定索引处的 char 值。
3 void ensureCapacity(int minimumCapacity)确保容量至少等于指定的最小值。
4 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)将字符从此序列复制到目标字符数组 dst。
5 int indexOf(String str)返回第一次出现的指定子字符串在该字符串中的索引。
6 int indexOf(String str, int fromIndex)从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。
7 int lastIndexOf(String str)返回最右边出现的指定子字符串在此字符串中的索引。
8 int lastIndexOf(String str, int fromIndex)返回 String 对象中子字符串最后出现的位置。
9 int length() 返回长度(字符数)。
10 void setCharAt(int index, char ch)将给定索引处的字符设置为 ch。
11 void setLength(int newLength)设置字符序列的长度。
12 CharSequence subSequence(int start, int end)返回一个新的字符序列,该字符序列是此序列的子序列。
13 String substring(int start)返回一个新的 String,它包含此字符序列当前所包含的字符子序列。
14 String substring(int start, int end)返回一个新的 String,它包含此序列当前所包含的字符子序列。
15 String toString()返回此序列中数据的字符串表示形式。

Java 中 StringBuffer 和 String 的区别

首先,String 是被 final 修饰的,他的长度是不可变的,就算调用 String 的 concat 方法,那也是把字符串拼接起来并重新创建一个对象,把拼接后的 String 的值赋给新创建的对象,而 StringBuffer 的长度是可变的,调用StringBuffer 的 append 方法,来改变 StringBuffer 的长度,并且,相比较于 StringBuffer,String 一旦发生长度变化,是非常耗费内存的!

JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么?

最简单的回答是,stringbuffer 基本没有适用场景,你应该在所有的情况下选择使用 stringbuiler,除非你真的遇到了一个需要线程安全的场景,如果遇到了,请务必在这里留言通知我。

然后,补充一点,关于线程安全,即使你真的遇到了这样的场景,很不幸的是,恐怕你仍然有 99.99….99% 的情况下没有必要选择 stringbuffer,因为 stringbuffer 的线程安全,仅仅是保证 jvm 不抛出异常顺利的往下执行而已,它可不保证逻辑正确和调用顺序正确。大多数时候,我们需要的不仅仅是线程安全,而是锁。

最后,为什么会有 stringbuffer 的存在,如果真的没有价值,为什么 jdk 会提供这个类?答案太简单了,因为最早是没有 stringbuilder 的,sun 的人不知处于何种愚蠢的考虑,决定让 stringbuffer 是线程安全的,然后大约 10 年之后,人们终于意识到这是一个多么愚蠢的决定,意识到在这 10 年之中这个愚蠢的决定为 java 运行速度慢这样的流言贡献了多大的力量,于是,在 jdk1.5 的时候,终于决定提供一个非线程安全的 stringbuffer 实现,并命名为 stringbuilder。顺便,javac 好像大概也是从这个版本开始,把所有用加号连接的 string 运算都隐式的改写成 stringbuilder,也就是说,从 jdk1.5 开始,用加号拼接字符串已经没有任何性能损失了。

如诸多评论所指出的,我上面说,”用加号拼接字符串已经没有任何性能损失了”并不严谨,严格的说,如果没有循环的情况下,单行用加号拼接字符串是没有性能损失的,java 编译器会隐式的替换成 stringbuilder,但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用 stringbuilder 吧。