Java教程

JavaSE——常用类-StringBuilder和StringBuffer

本文主要是介绍JavaSE——常用类-StringBuilder和StringBuffer,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

StringBuilder和StringBuffer

1、概述

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

image

2、常用方法

1、insert

package com.kuang.oop;

import java.util.HashMap;

public class Test {
    public static void main(String args[]) {
        System.out.println("---------- testInsertAPIs -----------");
        StringBuilder sbuilder = new StringBuilder();
        // 在位置0处插入字符数组
        sbuilder.insert(0, new char[] { 'a', 'b', 'c', 'd', 'e' });
        System.out.println(sbuilder);// abcde
        // 在位置0处插入字符数组。0表示字符数组起始位置,3表示长度
        sbuilder.insert(0, new char[] { 'A', 'B', 'C', 'D', 'E' }, 0, 3);
        System.out.println(sbuilder);// ABCabcde
        // 在位置0处插入float
        sbuilder.insert(0, 1.414f);
        System.out.println(sbuilder);// 1.414ABCabcde
        // 在位置0处插入double
        sbuilder.insert(0, 3.14159d);// 3.141591.414ABCabcde
        // 在位置0处插入boolean
        sbuilder.insert(0, true);// true3.141591.414ABCabcde
        // 在位置0处插入char
        sbuilder.insert(0, '\n');// 换行以后加上true3.141591.414ABCabcde
        System.out.println(sbuilder);
        // 在位置0处插入int
        sbuilder.insert(0, 100);
        System.out.println(sbuilder);// 100换行以后加上true3.141591.414ABCabcde
        // 在位置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);
        System.out.println(sbuilder);
        /*
         * 12345StringBUFFERStringBufferBUILDERStringBuilder12345100
         * true3.141591.414ABCabcde
         */
        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);
        // {1=one, 2=two, 3=three}
        // 12345StringBUFFERStringBufferBUILDERStringBuilder12345100
        // true3.141591.414ABCabcde
    }
}

2、append

package com.kuang.oop;

import java.util.HashMap;

public class Test {
    public static void main(String args[]) {

        /**
         * StringBuilder 的append()示例
         */

        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);
    }
}

------------------- testAppendAPIs -----------------
abcdeABC1.4143.14159true
10012345StringBuilderBUILDERStringBufferBUFFERString12345
{1=one, 2=two, 3=three}
字符编码

3、replace

package com.kuang.oop;


public class Test {
    public static void main(String args[]) {
        System.out.println("------------------- testReplaceAPIs-------------------");
        StringBuilder sbuilder;
        sbuilder = new StringBuilder("0123456789");
        sbuilder.replace(0, 3, "ABCDE");
        System.out.println(sbuilder);// 用ABCDE替换了012

        sbuilder = new StringBuilder("0123456789");
        sbuilder.reverse();
        System.out.printf("sbuilder=%s\n", sbuilder);// 反转为9876543210

        sbuilder = new StringBuilder("0123456789");
        sbuilder.setCharAt(0, 'M');
        System.out.printf("sbuilder=%s\n", sbuilder);// M123456789
        System.out.println();
    }
}

4、delete

package com.kuang.oop;

public class Test {
    public static void main(String args[]) {
        System.out.println("------------------- testDeleteAPIs-------------------");
        StringBuilder sbuilder;
        sbuilder = new StringBuilder("0123456789");
        // 删除位置0的字符,剩余字符是“123456789”。
        sbuilder.deleteCharAt(0);
        // 删除位置3(包括)到位置6(不包括)之间的字符,剩余字符是“sb=123789”。
        sbuilder.delete(3, 6);
        // 获取sb中从位置1开始的字符串,23789
        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

package com.kuang.oop;

public class Test {
    public static void main(String args[]) {
        StringBuilder sbuilder = new StringBuilder("abcAbcABCabCaBcAbCaBCabc");
        System.out.printf("sbuilder=%s\n", sbuilder);
        // 1. 从前往后,找出"bc"第一次出现的位置,1
        System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\")",
                sbuilder.indexOf("bc"));
        // 2. 从位置5开始,从前往后,找出"bc"第一次出现的位置,22
        System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\", 5)",
                sbuilder.indexOf("bc", 5));
        // 3. 从后往前,找出"bc"第一次出现的位置,22
        System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\")",
                sbuilder.lastIndexOf("bc"));
        // 4. 从位置4开始,从后往前,找出"bc"第一次出现的位置,4
        System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\", 4)",
                sbuilder.lastIndexOf("bc", 4));
        System.out.println();
    }
}

6、其他API

package com.kuang.oop;

public class Test {
    public static void main(String args[]) {
        System.out.println("----------- testOtherAPIs -----------");
        StringBuilder sbuilder = new StringBuilder("0123456789");
        int cap = sbuilder.capacity();
        System.out.printf("cap=%d\n", cap);// 26
        /*
         * 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);// 转换为字符6
        char[] carr = new char[4];
        sbuilder.getChars(3, 7, carr, 0);// [3,7)
        for (int i = 0; i < carr.length; i++) {
            System.out.printf("carr[%d]=%c ", i, carr[i]);// carr[0]=3 carr[1]=4 carr[2]=5 carr[3]=6
        }
        System.out.println();
    }
}

3、StringBuffer

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

4、小结

【String、StringBuffer、StringBuilder之间的区别】
首先需要说明的是:

  • String 字符串常量
  • StringBuffer 字符串变量(线程安全)
  • StringBuilder 字符串变量(非线程安全)
    在大多数情况下三者在执行速度方面的比较:StringBuilder > StringBuffer > String

解释:
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String
类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以
经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中
无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而
不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对
象经常改变的情况下。
为什么是大多数情况呢?

​ 在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,
所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中,
String 效率是远要比 StringBuffer 快的:

String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“
simple”).append(“ test”);

​ 你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本
一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
​ String S1 = “This is only a” + “ simple” + “test”;
​ 其实就是:String S1 = “This is only a simple test”;

​ 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象
的话,速度就没那么快了,譬如:
​ String S2 = “This is only a”;
​ String S3 = “ simple”;
​ String S4 = “ test”;

​ 大部分情况下StringBuilder的速度要大于StringBuffer:

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

5、面试题

image

这篇关于JavaSE——常用类-StringBuilder和StringBuffer的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!