自己实现一个StringBuffer

本文深入探讨了自制StringBuffer的实现细节,包括构造方法、追加、插入、删除、反转等核心功能,通过具体代码示例展示了如何管理和调整容量,以及如何进行字符串操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己动手实现了一个StringBuffer,算是个玩具代码,各种边界问题都没有做检查,但是对于理解StringBuffer来说,足够了。
实现过程中,查看了许多源码,弄明白了很多概念,其中还有一个问题是关于System.arraycopy()做删除操作,这篇算是未完待续吧!

package character;

import java.util.Arrays;

public class IStringBuffer {
    private char[] value;
    private int count;

    //default no-arg constructor
    public MyStringBuffer() {
        value = new char[16];
    }

    //constructor with capacity
    public MyStringBuffer(int capacity) {
        value = new char[capacity];
    }

    //constructor with string
    public MyStringBuffer(String str) {
        value = new char[str.length() + 16];
        append(str);
    }

    public static void main(String[] args) {
        MyStringBuffer msb = new MyStringBuffer("the");

        msb.append(" redpig is writting java programs for fun");
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.append('!');
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.insert(23, "funny ");
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.insert(23, ' ');
        msb.insert(23, 'a');
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.delete(23, 31);
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.delete(36);
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());

        msb.reverse();
        System.out.println("msb is: " + msb);
        System.out.println("length is: " + msb.length());
        System.out.println("capacity is: " + msb.capacity());
    }

    //追加字符串
    public void append(String str) {
        int newCapacity;
        if ((str.length() + count) - value.length > 0) {
            newCapacity = (value.length << 1) + 2;
            if (newCapacity - (str.length() + count) < 0)
                newCapacity = str.length() + count;
            value = Arrays.copyOf(value, newCapacity);
        }
        str.getChars(0, str.length(), value, count);
        count += str.length();
    }

    //追加字符
    public void append(char c) {
        this.append(String.valueOf(c));
    }

    public void insert(int pos, String str) {
        if ((str.length() + count) - value.length > 0) {
            int newCapacity;
            newCapacity = (value.length << 1) + 2;
            if (newCapacity - (str.length() + count) < 0)
                newCapacity = str.length() + count;
            value = Arrays.copyOf(value, newCapacity);
        }
        System.arraycopy(value, pos, value, pos + str.length(), count - pos);
        str.getChars(0, str.length(), value, pos);
        count += str.length();
    }

    public void insert(int pos, char c) {
        this.insert(pos, String.valueOf(c));
    }

    public void delete(int start, int end) {
        System.arraycopy(value, end, value, start, capacity() - end);
        count -= (end - start);
    }

    public void delete(int start) {
        this.delete(start, count);
    }

    public void reverse() {
        int n = count - 1;
        for (int j = (n - 1) >> 1; j >= 0; j--) {
            int k = n - j;
            char cj = value[j];
            char ck = value[k];
            value[j] = ck;
            value[k] = cj;
        }
    }

    public int length() {
        return count;
    }

    public int capacity() {
        return value.length;
    }

    public String toString() {
        return String.valueOf(value);
    }
}
<think>首先,用户的问题是:“我想将一个StringBuffer的内容复制到另一个StringBuffer 请问Java StringBuffer copy to another StringBuffer”。这是一个关于Java编程的问题,具体是如何复制一个StringBuffer对象的内容到另一个StringBuffer对象。 我需要参考系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 用户提供了引用内容: - 引用[1]:关于String、StringBuffer和StringBuilder的区别,强调StringBuffer是可变的。 - 引用[2]:StringBuffer的底层是byte数组,可以扩容。 - 引用[3]:StringBuffer是线程安全的,通过synchronized方法。 - 引用[4]:一个例子,用PL/SQL Developer复制SQL语句到StringBuffer。 用户的问题是关于复制StringBuffer内容,所以引用[4]似乎相关,因为它展示了如何构建StringBuffer,但用户真正需要的是复制内容。 关键点:StringBuffer是对象,复制内容时需要注意是浅拷贝还是深拷贝。在Java中,StringBuffer是可变的,所以直接赋值可能会导致引用同一个对象,而不是复制内容。 标准方法: - 使用`new StringBuffer(original.toString())`:这将创建一个新的StringBuffer对象,内容与原始相同。 - 或者使用`append`方法:`new StringBuffer().append(original)`。 在回答中,我需要: 1. 解释如何复制。 2. 提供代码示例。 3. 确保回答清晰、逐步。 4. 使用中文。 5. 在末尾生成相关问题。 6. 添加引用标识,如果引用内容相关。 引用内容: - [1] 和 [2] 解释了StringBuffer的底层实现。 - [3] 提到线程安全。 - [4] 是关于构建StringBuffer的,但用户的问题是关于复制。 对于复制,引用[4]可能不直接相关,但可以提到类似构建方式。 回答结构: 1. **介绍问题**:解释StringBuffer是可变的,复制内容需要创建新对象。 2. **方法**: - 使用`toString()`方法:创建一个新的StringBuffer,传入原始StringBuffer的字符串表示。 - 使用`append`方法:新StringBuffer追加原始内容。 - 讨论浅拷贝和深拷贝:由于StringBuffer是可变的,直接赋值会导致共享引用。 3. **代码示例**:提供Java代码展示如何复制。 4. **注意事项**:提到线程安全(如果相关),但这里主要是复制内容。 5. **生成相关问题**:在末尾添加相关问题。 生成相关问题: - 基于用户问题,如: 1. StringBuffer和StringBuilder在复制时有什么区别? 2. 如何高效地复制大型StringBuffer? 3. StringBuffer的线程安全如何影响复制操作? 确保LaTeX使用正确:用户问题中没有数学表达式,所以可能不需要。但如果有数学内容,使用$...$。 用户问题纯文本,所以回答中可能不需要LaTeX。 现在,构建回答: - 开头:直接回答问题。 - 步骤: 1. 解释为什么需要复制:因为StringBuffer是可变的,直接赋值会导致两个引用指向同一个对象。 2. 方法1:使用`toString()`:`StringBuffer copy = new StringBuffer(original.toString());` 3. 方法2:使用`append()`:`StringBuffer copy = new StringBuffer(); copy.append(original);` 4. 比较两种方法:效率上,`append`可能更好,因为它避免了创建临时字符串。 5. 代码示例。 - 注意事项: - 如果原始为null,需要处理。 - StringBuffer是线程安全的,但复制操作本身不需要额外同步,除非在多线程环境下。 - 结尾:生成相关问题。 引用标识:在回答中,如果提到引用内容,添加[^1]等。例如,提到StringBuffer的可变性时,引用[1]和[2]。 最终回答: - 用中文。 - 代码块使用Markdown格式。</think>### Java StringBuffer 内容复制到另一个 StringBufferJava 中,`StringBuffer` 是可变的字符串缓冲区(底层基于可变字节数组[^2]),直接赋值(如 `StringBuffer copy = original;`)会导致两个变量共享同一个对象引用。修改其中一个会影响另一个。因此,复制内容需要创建新对象并复制数据。以下是逐步解决方案: #### 1. **复制方法** - **方法1:使用 `toString()` 和构造器** 将原始 `StringBuffer` 转换为字符串,再传递给新 `StringBuffer` 的构造器。这是最直接的方式,但会创建一个临时字符串对象。 ```java StringBuffer original = new StringBuffer("Hello"); StringBuffer copy = new StringBuffer(original.toString()); // 复制内容 ``` - **验证**:修改 `copy` 不会影响 `original`: ```java copy.append(" World"); System.out.println(original); // 输出 "Hello" System.out.println(copy); // 输出 "Hello World" ``` - **方法2:使用 `append()` 方法** 初始化一个新 `StringBuffer`,然后追加原始对象的内容。`append()` 方法内部处理了内容复制,避免临时字符串创建,效率更高(尤其对大型数据)[^2]。 ```java StringBuffer original = new StringBuffer("Hello"); StringBuffer copy = new StringBuffer(); copy.append(original); // 复制内容 ``` - 底层原理:`append(StringBuffer)` 方法会提取原始对象的字符数组并追加到新对象中[^2]。 - **方法3:使用 `setLength()` 和 `getChars()`(高级)** 手动复制字符数组,适用于需要精细控制的场景: ```java StringBuffer original = new StringBuffer("Hello"); StringBuffer copy = new StringBuffer(original.length()); // 优化:预分配容量 copy.setLength(original.length()); // 设置相同长度 original.getChars(0, original.length(), copy.toString().toCharArray(), 0); ``` #### 2. **关键注意事项** - **性能优化**: - 在创建新 `StringBuffer` 时,指定初始容量(如 `new StringBuffer(original.length())`),减少扩容次数(扩容涉及数组拷贝,开销大)[^2]。 - 优先使用 `append()` 方法,避免 `toString()` 的临时对象开销。 - **线程安全**: `StringBuffer` 是线程安全的(方法用 `synchronized` 修饰[^3]),但复制操作本身不涉及多线程问题。如果多线程环境需修改对象,建议在复制后使用 `StringBuffer`;否则,用 `StringBuilder`(非线程安全但更快)。 - **空值处理**: 原始对象为 `null` 时会抛出 `NullPointerException`。添加检查: ```java StringBuffer copy = (original != null) ? new StringBuffer(original.toString()) : null; ``` #### 3. **完整代码示例** ```java public class StringBufferCopyExample { public static void main(String[] args) { // 原始 StringBuffer StringBuffer original = new StringBuffer("Java"); original.append(" is fun!"); // 复制内容 StringBuffer copy1 = new StringBuffer(original.toString()); // 方法1 StringBuffer copy2 = new StringBuffer(); copy2.append(original); // 方法2(推荐) // 测试修改独立性 copy1.insert(0, "Copy1: "); copy2.replace(0, 4, "Copy2"); System.out.println("Original: " + original); // 输出 "Java is fun!" System.out.println("Copy1: " + copy1); // 输出 "Copy1: Java is fun!" System.out.println("Copy2: " + copy2); // 输出 "Copy2 is fun!" } } ``` #### 4. **与类似类的区别** - **`StringBuilder`**:非线程安全,复制方法相同但性能更高(无同步开销)[^1][^3]。 - **`String`**:不可变,直接赋值即可复制(如 `String copy = original;`),但 `StringBuffer` 需显式复制[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值