java之StringBuilder和关于数组怎么扩容

String是不可变字符序列。
可变字符序列,StringBuffer和StringBuilder;
注意一下,其实StringBuffer和StringBuilder基本用法是一模一样的,
这里写图片描述
一个Eclipse的快捷键;Ctrl+T 快速显示当前类的继承结构。
注意一下两者的区别。
StringBulider;线程不安全,效率高,我们一般使用他。
StringBuffer; 线程安全但是效率不高。一般不使用它、

public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
//同样有final修饰,因此不能被修改继承了。
//继承与AbstractStringBuilder,看下他源码,一个抽象类,并且源码中,
//也有valve数组,只是这里是char[] value;不是private final;而是没有加修饰词,
//则是dafault类型,默认类型,只准许下同一个包下面的类改。(封装知识)

//因为StringBulider是继承父类的,因此也有value数组,等等一些东西。
构造方法;
public StringBuffer() {
        super(16);
    }
 直接调用父类的构造方法;
  AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
因此这个构造方法就是创建了一个为16的数组、默认16public StringBuffer(int capacity) {
        super(capacity);
    }
同样还是调用上面那个继承的方法,但是值不是16了,而是自己传入的。
public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
传入一个字符串,那么他字符串的长度就是这个字符串的长度再加16;
并且还调用了append()方法,(就是累加的意思)然后这个方法里面用调用父类的append方法,父类的方法中用调用了很多方法,这些都可以进行点击其源码进行了解。Ctrl+点击;
StringBuilder sb = new StringBuilder();//字符数组长度为16,默认;
StringBuilder sb1 = new StringBuilder(32);//那么字符数组的长度就是32;
StringBuilder sb2 = new StringBuilder("asrh");
//4+16;并且在value[]={‘a', 's','r','h',/u0000.........}
append()方法。在StringBuilder中很常用的一种方法。对字符串进行追加。
并且他还有很多重载方法。
1
sb2.append("123");//就进行了追加了,因此也验证了这是可变字符数列。
sb2.append(true);//在后面就直接添加ture了。
System.out.println(sb2);//返回asrh123true
2
 public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }
  注意一下append方法中有很多return this。这样有什么好处呢。
  通过return this可以实现方法链;
StringBuilder sb3 = new StringBuilder("asrh");
sb3.append("12").append("345");//可以进行叠加就是因为返回的是this、
System.out.println(sb3);//输出asrh12345
这个也解决了前面那个String中的问题,怎么去为字符串追加字符。其实用StringBuilder是最好的。
在append追加的时候,如果出现容量问题时是怎么解决的。
进去源码里面找。
子类append都会调用父类的append,则进入父类的append方法中看。
父类源码中有ensureCapacityInternal(count + len);//确保容量;
在点进源码,有expandCapacity(minimumCapacity);//扩容。
//则进行扩容了,不是真的这个数组扩容了,而是用新的进行了替换。
void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;//注意扩展的是两倍加2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();//抛出异常;
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
//同样数组大小定义了是不能再变的了,因此要重新建一个数组。在copyOf方法里面定义了一个新的数组。
public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

后面讲的容器也是这样的思路来进行扩容的。
修改数组。
 public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }
 、、、、、、、
    StringBuilder sb = new StringBuilder("abcdefghijklnmopqsr");
    sb.delete(2, 5).delete(2, 5);//删除索引,抱头不包尾;[2,5);是可以实现方法链的。因为return this。
    System.out.println(sb);//abijklnmopqsr
replac();替换,跟数组差不多,不同的就是实现机制不同。它是直接操作数组的,因为是可变的。
 public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }
insert;在索引处插入字符,索引往后推,
数组是插入不方便,查询方便。
public StringBuilder reverse()翻转一遍。

还有很多方法,其实跟String都是类似的。

遇到问题,不要一开始就说不可以,一开始就要说可以,然后在运转自己的小宇宙。你一说不可以那就真的不可以了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值