how2j.cn


工具版本兼容问题
StringBuffer是可变长的字符串


本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频



5分9秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器



关键字 简介 示例代码
append delete insert reverse
追加 删除 插入 反转
示例代码
length capacity
长度 容量
示例代码
练习-StringBuffer性能
示例代码
答案-StringBuffer性能
示例代码
练习-MyStringBuffer
示例代码
答案-MyStringBuffer
示例代码
示例 1 : 追加 删除 插入 反转   
示例 2 : 长度 容量   
示例 3 : 练习-StringBuffer性能   
示例 4 : 答案-StringBuffer性能   
示例 5 : 练习-MyStringBuffer   
示例 6 : 答案-MyStringBuffer   

示例 1 :

追加 删除 插入 反转

edit
append追加
delete 删除
insert 插入
reverse 反转
package character; public class TestString { public static void main(String[] args) { String str1 = "let there "; StringBuffer sb = new StringBuffer(str1); //根据str1创建一个StringBuffer对象 sb.append("be light"); //在最后追加 System.out.println(sb); sb.delete(4, 10);//删除4-10之间的字符 System.out.println(sb); sb.insert(4, "there ");//在4这个位置插入 there System.out.println(sb); sb.reverse(); //反转 System.out.println(sb); } }
为什么StringBuffer可以变长?
和String内部是一个字符数组一样,StringBuffer也维护了一个字符数组。 但是,这个字符数组,留有冗余长度
比如说new StringBuffer("the"),其内部的字符数组的长度,是19,而不是3,这样调用插入和追加,在现成的数组的基础上就可以完成了。
如果追加的长度超过了19,就会分配一个新的数组,长度比原来多一些,把原来的数据复制到新的数组中,看上去 数组长度就变长了 参考MyStringBuffer
length: “the”的长度 3
capacity: 分配的总空间 19

注: 19这个数量,不同的JDK数量是不一样的
package character; public class TestString { public static void main(String[] args) { String str1 = "the"; StringBuffer sb = new StringBuffer(str1); System.out.println(sb.length()); //内容长度 System.out.println(sb.capacity());//总空间 } }
package character;
 
public class TestString {
 
    public static void main(String[] args) {
        String str1 = "the";

        StringBuffer sb = new StringBuffer(str1);
        
        System.out.println(sb.length()); //内容长度
        
        System.out.println(sb.capacity());//总空间
 
    }
 
}

示例 3 :

练习-StringBuffer性能

edit  姿势不对,事倍功半! 点击查看做练习的正确姿势
String与StringBuffer的性能区别?

生成10位长度的随机字符串
然后,先使用String的+,连接10000个随机字符串,计算消耗的时间
然后,再使用StringBuffer连接10000个随机字符串,计算消耗的时间

提示: 使用System.currentTimeMillis() 获取当前时间(毫秒)
练习-StringBuffer性能
示例 4 :

答案-StringBuffer性能

edit
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费3个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 基础总计0个答案 (总共需要0积分)
查看本答案会花费3个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 基础总计0个答案 (总共需要0积分)
账号未激活 账号未激活,功能受限。 请点击激活
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频

7分27秒 本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器


package character; public class TestString { public static void main(String[] args) { int total = 10000; String s = randomString(10); StringBuffer sb = new StringBuffer(); String str1 = ""; long start = System.currentTimeMillis(); for (int i = 0; i <total; i++) { str1+=s; } long end = System.currentTimeMillis(); System.out.printf("使用字符串连接+的方式,连接%d次,耗时%d毫秒%n",total,end-start); total *=100; start = System.currentTimeMillis(); for (int i = 0; i <total; i++) { sb.append(s); } end = System.currentTimeMillis(); System.out.printf("使用StringBuffer的方式,连接%d次,耗时%d毫秒%n",total,end-start); } private static String randomString(int length) { String pool = ""; for (short i = '0'; i <= '9'; i++) { pool += (char) i; } for (short i = 'a'; i <= 'z'; i++) { pool += (char) i; } for (short i = 'A'; i <= 'Z'; i++) { pool += (char) i; } char cs[] = new char[length]; for (int i = 0; i < cs.length; i++) { int index = (int) (Math.random() * pool.length()); cs[i] = pool.charAt(index); } String result = new String(cs); return result; } }
示例 5 :

练习-MyStringBuffer

edit  姿势不对,事倍功半! 点击查看做练习的正确姿势
根据接口IStringBuffer ,自己做一个MyStringBuffer
package character; public interface IStringBuffer { public void append(String str); //追加字符串 public void append(char c); //追加字符 public void insert(int pos,char b); //指定位置插入字符 public void insert(int pos,String b); //指定位置插入字符串 public void delete(int start); //从开始位置删除剩下的 public void delete(int start,int end); //从开始位置删除结束位置-1 public void reverse(); //反转 public int length(); //返回长度 }
package character;
 
public interface IStringBuffer {
    public void append(String str); //追加字符串 
    public void append(char c);  //追加字符
    public void insert(int pos,char b); //指定位置插入字符
    public void insert(int pos,String b); //指定位置插入字符串
    public void delete(int start); //从开始位置删除剩下的
    public void delete(int start,int end); //从开始位置删除结束位置-1
    public void reverse(); //反转
    public int length(); //返回长度
}
package character; public class MyStringBuffer implements IStringBuffer{ }
package character;
public class MyStringBuffer implements IStringBuffer{
}
示例 6 :

答案-MyStringBuffer

edit
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费5个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 基础总计0个答案 (总共需要0积分)
查看本答案会花费5个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 基础总计0个答案 (总共需要0积分)
账号未激活 账号未激活,功能受限。 请点击激活
因为这个答案比较复杂,为了便于理解和消化,专门开了一个章节来讲解这个答案: MyStringBuffer


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2023-10-12 功能实现了,但跟StringBuffer一点关系没有
陈缘觉




功能实现了,但跟StringBuffer一点关系没有。不知道是不是没能理解题意。
public class MyStringBuffer implements IStringBuffer {
    public String str;
    public MyStringBuffer(String str) {
        this.str = str;
    }
    public void append(String str) {
        this.str += str;
    }
    public void append(char c) {
        char[]cs = {c};
        str += new String(cs);
    };
    public void insert(int pos,char b) {
        char[]cs = {b};
        str = str.substring(0,pos) + new String(cs) +str.substring(pos);
    };
    public void insert(int pos,String b) {
        str = str.substring(0,pos) + b +str.substring(pos);
    };
    public void delete(int start) {
        str = str.substring(0,start);
    };
    public void delete(int start,int end) {
        str = str.substring(0,start) + str.substring(end);
    };
    public void reverse() {
        char [] cs = new char[str.length()];
        for(int i=0,j=str.length()-1;i<str.length();i++,j--) {
            cs[i] = str.charAt(j);
        }
        str = new String(cs);
    };
    public int length() {
        return str.length();
    };
    public static void main(String[] args) {
        MyStringBuffer str1 = new MyStringBuffer("c41234");
        str1.length();
        System.out.println(str1.length());
    }
}

							


1 个答案

晚安嘛
答案时间:2024-03-18
用的是字符数组,会麻烦一点



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2023-08-06 MyStringBuffer
旧时亭台阁




字符串拼接耗时:1323 StringBuffer 耗时:0 MyStringBuffer 耗时:7
public class MyStringBuffer implements IStringBuffer {

    /**
     * 默认的空间大小
     */
    private static final int DEFAULT_CAPACITY = 19;

    /**
     * 字符数组
     */
    private char[] chars = new char[DEFAULT_CAPACITY];

    /**
     * 字符数组的有效长度
     */
    private int usedLen = 0;

    public MyStringBuffer() {
    }

    public MyStringBuffer(String str) {
        append(str);
    }

    @Override
    public void append(String str) {
        ensure(str.length());
        for (int i = 0; i < str.length(); i++) {
            chars[usedLen++] = str.charAt(i);
        }
    }

    @Override
    public void append(char c) {
        ensure(1);
        chars[usedLen++] = c;
    }

    @Override
    public void insert(int pos, char b) {
        // 插入位置是末尾,执行追加
        if (pos == usedLen) {
            append(b);
            return;
        }
        // 检验插入位置的有效性
        if (invalidate(pos)) {
            return;
        }
        ensure(1);
        System.arraycopy(chars, pos, chars, pos + 1, usedLen - pos);
        chars[pos] = b;
        ++usedLen;
    }

    @Override
    public void insert(int pos, String b) {
        // 插入位置是末尾,执行追加
        if (pos == usedLen) {
            append(b);
            return;
        }
        // 检验插入位置的有效性
        if (invalidate(pos)) {
            return;
        }
        ensure(b.length());
        System.arraycopy(chars, pos, chars, pos + b.length(), usedLen - pos);
        System.arraycopy(b.toCharArray(), 0, chars, pos, b.length());
        usedLen += b.length();
    }

    @Override
    public void delete(int start) {
        if (invalidate(start)) {
            return;
        }
        usedLen = start;
    }

    @Override
    public void delete(int start, int end) {
        if (invalidate(start) || end <= start) {
            return;
        }
        while (end < usedLen) {
            chars[start++] = chars[end++];
        }
        usedLen = start;
    }

    @Override
    public void reverse() {
        for (int i = 0, j = usedLen - 1; i < j; i++, j--) {
            char tmp = chars[i];
            chars[i] = chars[j];
            chars[j] = tmp;
        }
    }

    @Override
    public int length() {
        return usedLen;
    }

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

    @Override
    public String toString() {
        return String.valueOf(chars, 0, usedLen);
    }

    /**
     * 验证编辑位置是否有效
     *
     * @param pos 下标
     * @return 是否有效
     */
    private boolean invalidate(int pos) {
        return pos < 0 || pos >= usedLen;
    }

    /**
     * 添加字符时,确保空间大小足够
     *
     * @param add 添加的字符的个数
     */
    private void ensure(int add) {
        // 需要的容量
        int needCap = usedLen + add;
        // 计算容纳需要的容量
        int finalCap = chars.length;
        while (finalCap < needCap) {
            finalCap <<= 1;
        }
        // 扩容
        if (finalCap != chars.length) {
            expand(finalCap);
        }
    }

    /**
     * 扩容
     *
     * @param finalCap 最终容量
     */
    private void expand(int finalCap) {
        char[] bak = new char[finalCap];
        System.arraycopy(chars, 0, bak, 0, usedLen);
        chars = bak;
    }


    public static void main(String[] args) {
        final int ADD_LEN = 10, LOOP = 10000;
        final String BASE_STR = randomStr(ADD_LEN);

        String testStr = BASE_STR;
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < LOOP; i++) {
            testStr += randomStr(ADD_LEN);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("字符串拼接耗时:" + (endTime - startTime));


        StringBuffer sf = new StringBuffer(BASE_STR);
        startTime = System.currentTimeMillis();
        for (int i = 0; i < LOOP; i++) {
            sf.append(randomStr(ADD_LEN));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer 耗时:" +  (endTime - startTime));


        MyStringBuffer msf = new MyStringBuffer(BASE_STR);
        startTime = System.currentTimeMillis();
        for (int i = 0; i < LOOP; i++) {
            msf.append(randomStr(ADD_LEN));
        }
        endTime = System.currentTimeMillis();
        System.out.println("MyStringBuffer 耗时:" +  (endTime - startTime));
    }

    /**
     * 随机生成字符串
     *
     * @param length 长度
     * @return 定长的随机字符串
     */
    public static String randomStr(int length) {
        String result = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] chars = new char[length];
        for (int i = 0; i < chars.length; i++) {
            int index = (int) (Math.random() * result.length());
            chars[i] = result.charAt(index);
        }
        return new String(chars);
    }
}

							


1 个答案

巧夺天工
答案时间:2024-03-13
NBNB



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2022-05-27 答案
2022-05-10 练习1
2022-03-03 我自己的答案,很笨的答案,不过挺容易懂的。


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 39 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 JAVA 基础-数字与字符串-StringBuffer 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图