前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己动手实现Java中的StringBuffer类

自己动手实现Java中的StringBuffer类

作者头像
Wizey
发布2018-08-30 09:42:40
7500
发布2018-08-30 09:42:40
举报
文章被收录于专栏:编程心路

在网上复习 Java 的基础知识,看到 String 和 StringBuffer 这里,简单的实现了下 StringBuffer 这个类,并对 String,StringBuffer,MyStringBuffer(自己实现的 StringBuffer 类名)做了拼接字符串的性能测试。

String 和 StringBuffer 内部都是通过字符数组实现的,但是 String 内部的字符数组是在第一次赋值时就固定了长度的,不可再更改,而 StringBuffer 内部的字符数组是留有冗余长度的,如果超过初始容量,就动态的增大数组的容量,使其看起来像是一个变长的数组。

在进行大量的字符串拼接时,强烈推荐 StringBuffer 而不是 String,因为 String 拼接字符串,没拼接一次都需要创建一个 String 对象来存放要拼接的字符串。而 StringBuffer 拼接字符串只是在原有字符串对象的基础上扩展字符数组的空间,并不会创建新的 StringBuffer 对象,这点也是 StringBuffer 比 String 速度快的原因。

下面就来简单实现一下 StringBuffer,取名为 MyStringBuffer。

代码语言:javascript
复制
public class MyStringBuffer{
    private int capacity = 16; // 初始容量
    private int length = 0; // 字面值字符串的长度
    private char[] value;
    
    public MyStringBuffer() {
        value = new char[capacity];
    }
    
    public MyStringBuffer(String str) {
        if(str == null) {
            return;
        }
        length = str.length();
        // str字符串的长度大于初始容量
        if(capacity < length) {
            capacity += length;
            value = new char[capacity];
            System.arraycopy(str.toCharArray(), 0, value, 0, length);
        } else {
            value = new char[capacity];
            System.arraycopy(str.toCharArray(), 0, value, 0, length);
        }
    }
    
    public void append(String str) {
        insert(length, str);
    }

    public void append(char c) {
        insert(length, String.valueOf(c));
    }

    public void insert(int pos, String str) {
        if(pos < 0 || pos > length || str == null) {
            return;
        }
        // 容量不够
        while((length + str.length()) > capacity) {
            capacity += length + str.length();
            char[] newValue = new char[capacity];
            System.arraycopy(value, 0, newValue, 0, length);
            value = newValue;
        }
        char[] temp = str.toCharArray();
        // 先移后插
        System.arraycopy(value, pos, value, pos + temp.length, length - pos);
        System.arraycopy(temp, 0, value, pos, temp.length);
        length += temp.length;
    }

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

    public void delete(int start) {
        delete(start, length - 1);
    }

    public void delete(int start, int end) {
        if(start < 0 || start > length || end < 0 || end > (length - 1) || start > length) {
            return;
        }
        System.arraycopy(value, end, value, start, length - end);
        length -= (end - start);
    }

    public void reverse() {
        // 方法一 间接法
        /*char[] temp = new char[value.length];
        for(int i = 0, j = length; i < length; i++, j--) {
            temp[i] = value[j - 1];
        }
        value = temp;*/
        // 方法二 直接法
        for(int i = 0; i < length / 2; i++) {
            char temp = value[i];
            value[i] = value[length - i - 1];
            value[length - i - 1] = temp;
        }
    }

    public int length() {
        return length;
    }
    
    public String toString() {
        char[] realValue = new char[length];
        System.arraycopy(value, 0, realValue, 0, length);
        return new String(realValue);
    }

    public int capacity() {
        return capacity;
    }
}

下面是 MyStringBuffer 的测试类 MyStringBufferTest。

代码语言:javascript
复制
package com.wenshixin.character;

import org.junit.Test;

public class MyStringBufferTest {
    final int TIMES = 1000000; // 循环次数
    final double DIVISOR = 1000000.0; // 除数
    
    @Test
    public void constructorTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("Weizhiwen");
        System.out.println(myStringBuffer);
        MyStringBuffer longStringBuffer = new MyStringBuffer("It's a long road, the only key.");
        System.out.println(longStringBuffer);
    }
    
    @Test
    public void lengthAndCapacityTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("Weizhiwen");
        System.out.println("length:"+myStringBuffer.length());
        System.out.println("capacity:"+myStringBuffer.capacity());
        MyStringBuffer longStringBuffer = new MyStringBuffer("It's a long road, the only key.");
        System.out.println("length:" + longStringBuffer.length());
        System.out.println("capacity:" + longStringBuffer.capacity());
    }
    
    @Test
    public void reverseTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("Weizhiwen");
        myStringBuffer.reverse();
        System.out.println(myStringBuffer);
    }
    
    @Test
    public void insertTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("Weiwen");
        myStringBuffer.insert(3, "zhi");
        System.out.println(myStringBuffer);
        myStringBuffer.insert(0, "I'm ");
        System.out.println(myStringBuffer);
        myStringBuffer.insert(myStringBuffer.length(), "!");
        System.out.println(myStringBuffer);
        myStringBuffer.insert(myStringBuffer.length(), "\nIt's a long road, the only key.");
        System.out.println(myStringBuffer);
        myStringBuffer.insert(-1, "nothing");
        System.out.println("低于下限位置插入值,显示:" + myStringBuffer);
        myStringBuffer.insert(myStringBuffer.length() + 2, "nothing");
        System.out.println("高于上限位置插入值,显示:" + myStringBuffer);
    }
    
    @Test
    public void appendTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer();
        myStringBuffer.append("I'm Weizhiwen");
        System.out.println(myStringBuffer);
        myStringBuffer.append("!");
        System.out.println(myStringBuffer);
    }
    
    @Test
    public void deleteTest() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("I'm not Weizhiwen!");
        myStringBuffer.delete(3, 7);
        System.out.println(myStringBuffer);
    }
    
    @Test
    public void stringPerformenceTest() {
        String string = "1";
        Long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 0; i < TIMES; i++) {
            string += "0";
        }
        Long endTime = System.currentTimeMillis();
        System.out.println(endTime);
        double avgTime = (endTime - startTime) / DIVISOR; 
        System.out.println("String平均一次的拼接时间为:" + avgTime + "毫秒。");
    }
    
    @Test
    public void stringBufferPerformenceTest() {
        StringBuffer stringBuffer = new StringBuffer("1");
        Long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 0; i < TIMES; i++) {
            stringBuffer.append("0");
        }
        Long endTime = System.currentTimeMillis();
        System.out.println(endTime);
        double avgTime = (endTime - startTime) / DIVISOR; 
        System.out.println("StringBuffer平均一次的拼接时间为:" + avgTime + "毫秒。");
    }
    
    @Test
    public void myStringBufferPerformence() {
        MyStringBuffer myStringBuffer = new MyStringBuffer("1");
        Long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 0; i < TIMES; i++) {
            myStringBuffer.append("0");
        }
        Long endTime = System.currentTimeMillis();
        System.out.println(endTime);
        double avgTime = (endTime - startTime) / DIVISOR; 
        System.out.println("MyStringBuffer平均一次的拼接时间为:" + avgTime + "毫秒。");
    }
}

我分别做了循环 1000 次,10,000 次,100,000 次,1000,000 次拼接,结果是平均拼接时间 t(StringBuffer) < t(MyStringBuffer) < t(String)。

通过自己实现 StringBuffer,加深了对 StringBuffer 和 String 者两个类的理解,Java 基础还需加强。

个人 GitHub 地址:https://github.com/weizhiwen,欢迎来访。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.07.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档