9.StringBuilder 和 StringBuffer

StringBuilder 和 StringBuffer

1、概述

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
}

StringBuilder 是一个可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。 StringBuffer 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,前者是非线程安全的,后者是线程安全的。

StringBuilder 和 CharSequence之间的关系图如下:

在这里插入图片描述

2、常用方法

(1)insert
private static void testInsertAPIs(){
    System.out.println("---------- testInsertAPIs -----------");
    StringBuilder sbuilder = new StringBuilder();
    // 在位置0处插入字符数组
    sbuilder.insert(0, new char[]{'a', 'b', 'c', 'd', 'e'});
    // 在位置0处插入字符数组。0表示字符数组起始位置,3表示长度
    sbuilder.insert(0, new char[]{'A', 'B', 'C', 'D', 'E'}, 0, 3);
    // 在位置0处插入float
    sbuilder.insert(0, 1.414f);
    // 在位置0处插入double
    sbuilder.insert(0, 3.14159d);
    // 在位置0处插入boolean
    sbuilder.insert(0, true);
    // 在位置0处插入char
    sbuilder.insert(0, '\n');
    // 在位置0处插入int
    sbuilder.insert(0, 100);
    // 在位置0处插入long
    sbuilder.insert(0, 12345L);
    // 在位置0处插入StringBuilder对象
    sbuilder.insert(0, new StringBuilder("StringBuilder"));
    // 在位置0处插入StringBuilder对象。6表示被在位置0处插入对象的起始位置(包括),13是
    结束位置(不包括)
        sbuilder.insert(0, new StringBuilder("STRINGBUILDER"), 6, 13);
    // 在位置0处插入StringBuffer对象。
    sbuilder.insert(0, new StringBuffer("StringBuffer"));
    // 在位置0处插入StringBuffer对象。6表示被在位置0处插入对象的起始位置(包括),12是结
    束位置(不包括)
        sbuilder.insert(0, new StringBuffer("STRINGBUFFER"), 6, 12);
    // 在位置0处插入String对象。
    sbuilder.insert(0, "String");
    // 在位置0处插入String对象。1表示被在位置0处插入对象的起始位置(包括),6是结束位置(不
    包括)
        sbuilder.insert(0, "0123456789", 1, 6);
    sbuilder.insert(0, '\n');
    // 在位置0处插入Object对象。此处以HashMap为例
    HashMap map = new HashMap();
    map.put("1", "one");
    map.put("2", "two");
    map.put("3", "three");
    sbuilder.insert(0, map);
    System.out.printf("%s\n\n", sbuilder);
}
(2)append
/**
* StringBuilder 的append()示例
*/
private static void testAppendAPIs() {
    System.out.println("------------------- testAppendAPIs -------------------");
    StringBuilder sbuilder = new StringBuilder();
    // 追加字符数组
    sbuilder.append(new char[]{'a','b','c','d','e'});
    // 追加字符数组。0表示字符数组起始位置,3表示长度
    sbuilder.append(new char[]{'A','B','C','D','E'}, 0, 3);
    // 追加float
    sbuilder.append(1.414f);
    // 追加double
    sbuilder.append(3.14159d);
    // 追加boolean
    sbuilder.append(true);
    // 追加char
    sbuilder.append('\n');
    // 追加int
    sbuilder.append(100);
    // 追加long
    sbuilder.append(12345L);
    // 追加StringBuilder对象
    sbuilder.append(new StringBuilder("StringBuilder"));
    // 追加StringBuilder对象。6表示被追加对象的起始位置(包括),13是结束位置(不包括)
    sbuilder.append(new StringBuilder("STRINGBUILDER"), 6, 13);
    // 追加StringBuffer对象。
    sbuilder.append(new StringBuffer("StringBuffer"));
    // 追加StringBuffer对象。6表示被追加对象的起始位置(包括),12是结束位置(不包括)
    sbuilder.append(new StringBuffer("STRINGBUFFER"), 6, 12);
    // 追加String对象。
    sbuilder.append("String");
    // 追加String对象。1表示被追加对象的起始位置(包括),6是结束位置(不包括)
    sbuilder.append("0123456789", 1, 6);
    sbuilder.append('\n');
    // 追加Object对象。此处以HashMap为例
    HashMap map = new HashMap();
    map.put("1", "one");
    map.put("2", "two");
    map.put("3", "three");
    sbuilder.append(map);
    sbuilder.append('\n');
    // 追加unicode编码
    sbuilder.appendCodePoint(0x5b57); // 0x5b57是“字”的unicode编码
    sbuilder.appendCodePoint(0x7b26); // 0x7b26是“符”的unicode编码
    sbuilder.appendCodePoint(0x7f16); // 0x7f16是“编”的unicode编码
    sbuilder.appendCodePoint(0x7801); // 0x7801是“码”的unicode编码
    System.out.printf("%s\n\n", sbuilder);
}
(3)replace
/**
* StringBuilder 的replace()示例
*/
private static void testReplaceAPIs() {
    System.out.println("------------------- testReplaceAPIs-------------------");
    StringBuilder sbuilder;
    sbuilder = new StringBuilder("0123456789");
    sbuilder.replace(0, 3, "ABCDE");
    System.out.printf("sbuilder=%s\n", sbuilder);
    sbuilder = new StringBuilder("0123456789");
    sbuilder.reverse();
    System.out.printf("sbuilder=%s\n", sbuilder);
    sbuilder = new StringBuilder("0123456789");
    sbuilder.setCharAt(0, 'M');
    System.out.printf("sbuilder=%s\n", sbuilder);
    System.out.println();
}
(4)delete
private static void testDeleteAPIs() {
    System.out.println("------------------- testDeleteAPIs -------------------");
    StringBuilder sbuilder = new StringBuilder("0123456789");
    // 删除位置0的字符,剩余字符是“123456789”。
    sbuilder.deleteCharAt(0);
    // 删除位置3(包括)到位置6(不包括)之间的字符,剩余字符是“123789”。
    sbuilder.delete(3,6);
    // 获取sb中从位置1开始的字符串
    String str1 = sbuilder.substring(1);
    // 获取sb中从位置3(包括)到位置5(不包括)之间的字符串
    String str2 = sbuilder.substring(3, 5);
    // 获取sb中从位置3(包括)到位置5(不包括)之间的字符串,获取的对象是CharSequence对
    象,此处转型为String
        String str3 = (String)sbuilder.subSequence(3, 5);
    System.out.printf("sbuilder=%s\nstr1=%s\nstr2=%s\nstr3=%s\n",
                      sbuilder, str1, str2, str3);
}
(5)index
/**
* StringBuilder 中index相关API演示
*/
private static void testIndexAPIs() {
    System.out.println("-------------------------------- testIndexAPIs --------------------------------");
    StringBuilder sbuilder = new StringBuilder("abcAbcABCabCaBcAbCaBCabc");
    System.out.printf("sbuilder=%s\n", sbuilder);
    // 1. 从前往后,找出"bc"第一次出现的位置
    System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\")",
                      sbuilder.indexOf("bc"));
    // 2. 从位置5开始,从前往后,找出"bc"第一次出现的位置
    System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\", 5)",
                      sbuilder.indexOf("bc", 5));
    // 3. 从后往前,找出"bc"第一次出现的位置
    System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\")",
                      sbuilder.lastIndexOf("bc"));
    // 4. 从位置4开始,从后往前,找出"bc"第一次出现的位置
    System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\", 4)",
                      sbuilder.lastIndexOf("bc", 4));
    System.out.println();
}
(6)其他API
/**
* StringBuilder 的其它API示例
*/
private static void testOtherAPIs() {
    System.out.println("----------- testOtherAPIs -----------");
    StringBuilder sbuilder = new StringBuilder("0123456789");
    int cap = sbuilder.capacity();
    System.out.printf("cap=%d\n", cap);
    /*
capacity()返回的是字符串缓冲区的容量
StringBuffer( ); 分配16个字符的缓冲区
StringBuffer( int len ); 分配len个字符的缓冲区
StringBuffer( String s ); 除了按照s的大小分配空间外,再分配16个 字符的缓冲区
你的StringBuffer是用字符构造的,"0123456789"的长度是10另外再分配16个字符,所
以一共是26。
*/
    char c = sbuilder.charAt(6);
    System.out.printf("c=%c\n", c);
    char[] carr = new char[4];
    sbuilder.getChars(3, 7, carr, 0);
    for (int i=0; i<carr.length; i++){
        System.out.printf("carr[%d]=%c ", i, carr[i]);
    }
    System.out.println();
}

3、StringBuffer

和StringBulider用法差不多,不过多介绍,主要看一下三者的区别

4、小结

【String、StringBuffer、StringBuilder之间的区别】
首先需要说明的是:
  • String 字符串常量
  • StringBuffer 字符串变量(线程安全)
  • StringBuilder 字符串变量(非线程安全)

在大多数情况下三者在执行速度方面的比较:StringBuilder > StringBuffer > String

java.lang.StringBuilder一个可变的字符序列是5.0新增的。(大多数情况下就是我们是在单线程下进行 的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的)此类提供一个与StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个 线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer 要快。两者的方法基本相同

对于三者使用的总结:
  1. 如果要操作少量的数据用 = String
  2. 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
  3. 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

5、面试题的回答

StringBuilder 与StringBuffer的区别,StringBuilder与String的区别
  1. StringBuilder效率高,线程不安全,StringBuffer效率低,线程安全。
  2. String是不可变字符串,StringBuilder是可变字符串。为什么有这样的差异,可以深入源码去解析, 比如String类内的 priver final char value[] 等方法的原因。
  3. 如果是简单的声明一个字符串没有后续过多的操作,使用String,StringBuilder均可,若后续对字符穿 做频繁的添加,删除操作,或者是在循环当中动态的改变字符穿的长度应该用StringBuilder。使用String 会产生多余的字符串,占用内存空间。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
String、StringBuilderStringBuffer之间的区别主要有以下几点: 1. 可变性: String是不可变字符串,即一旦创建就不能修改。而StringBuilderStringBuffer是可变字符串,可以随意修改其内容。 2. 线程安全性: StringBuffer是线程安全的,可以在多线程环境下使用,而StringBuilder是线程不安全的,不适用于多线程环境。这是因为StringBuffer的方法都使用了synchronized关键字来保证线程安全性,而StringBuilder没有。 3. 执行速度: 在执行速度方面,StringBuilder的性能最好,其次是StringBuffer,而String的执行速度最慢。这是因为String每次对字符串进行修改时,都会创建一个新的String对象,而StringBuilderStringBuffer则是直接在原有的对象上进行修改,避免了创建新对象的开销。 综上所述,String是不可变的字符串,StringBuilderStringBuffer是可变的字符串,StringBuilder是线程不安全的但执行速度较快,而StringBuffer是线程安全的但执行速度稍慢。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [String 和 StringBuilder 以及 StringBuffer的区别](https://blog.csdn.net/weixin_43682323/article/details/128036953)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [String/StringBuilder/StringBuffer之间的区别](https://blog.csdn.net/weixin_33826268/article/details/92944578)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [6. String StringBuffer StringBuilder 区别](https://blog.csdn.net/qq_44791484/article/details/115363705)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值