String系列-----AbstractStringBuilder

1. AbstractStringBuilder是StringBuffer和StringBuilder的父类
package com.amazing.jdk.string_2017_12_31;

import java.util.Arrays;


public abstract class MyAbstractStringBuilder {
    //用来存储字节
    char[] value;
    //字节的数量
    int count;

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 无参的构造方法
     */
    MyAbstractStringBuilder(){}

    /**
     * 有参的构造方法
     * @param capacity
     * @return
     */
    MyAbstractStringBuilder(int capacity){
        value = new char[capacity];
    }

    /**
     * 已存储字符长度
     * @return
     */
    public int length(){
        return count;
    }

    /**
     * 字符数组长度
     * @return
     */
    public int capacity(){
        return value.length;
    }

    /**
     * 确保不会数组下标越界
     *   length --->2*length+2 --->max_size---> Integer.Max
     * @param minimumCapacity
     */
    public void ensureCapacity(int minimumCapacity){
        if(minimumCapacity>0){
            //大于0
            if(minimumCapacity-value.length>0){
                //长度大于字符数组长度(容量不够),进行扩容
                int newCapacity = (value.length*2)+2; //位运算 (value.length << 1) + 2;
                if(newCapacity - minimumCapacity < 0){
                    //扩容两倍还是不够,就让数组长度等于传进来的数
                    newCapacity = minimumCapacity;
                }

                if(MAX_ARRAY_SIZE - minimumCapacity > 0){

                    value =Arrays.copyOf(value,newCapacity);
                }else {
                    if(minimumCapacity>Integer.MAX_VALUE){
                        //超出内存错误
                        throw new OutOfMemoryError();
                    }
                    value=Arrays.copyOf(value,minimumCapacity);

                }

            }

        }
    }

    /**
     * 对应下标的字符
     * @param index
     * @return
     */
    public char charAt(int index){
        if(index<0 || index>=count){
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];

    }

    /**
     * 追加:null
     * @return
     */
    public MyAbstractStringBuilder appendNull(){
        int c=count;
        ensureCapacity(c+4);
        final char[] value=this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }

/**
* 追加内容 重写Appendable接口的方法
* @param c
* @return
*/
public MyAbstractStringBuilder append(char c){
ensureCapacity(count+1);
value[count++] = c;
return this;
}

/**
* 字符串逆序输出
* @param str
* @return
*/
public String reverse(String str){
char[] charStr = str.toCharArray();
int len = str.length();
int n = len-1;
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j;
char cj = charStr[j];
char ck = charStr[k];
charStr[j] = ck;
charStr[k] = cj;
}

return new String(charStr);
}

  public abstract String toString(); //唯一的一个抽象方法:toString(),实现类重写该方法

  final char[] getValue() { 唯一的一个final方法:getValue(),得到value数组。可以对其直接操作
return value;
  }

}

2. 把一个字符串反转的方法:

public static String reverse1(String str){
        return new StringBuffer(str).reverse().toString();
    }

    public static String reverse2(String str){
        char[] charStr = str.toCharArray();//把字符串转成字符数组
        String reverse = "";//空数组用来装反转之后的字符串
        for(int i=charStr.length-1;i>=0;i--){ //倒序遍历
            reverse+=charStr[i];

        }
        return reverse;
    }

    public static String reverse3(String str){
        int len = str.length();
        String reverse = "";
        for (int i = 0; i <len ; i++) {
            reverse = str.charAt(i)+reverse; //倒着加,没啥卵用(效率不会提高)
        }
        return reverse;

    }

//注意理解这个算法 public static String reverse4(String str){ char[] charStr = str.toCharArray(); int len = str.length(); int n = len-1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = charStr[j]; char ck = charStr[k]; charStr[j] = ck; charStr[k] = cj; } return new String(charStr); }

 3.注意:

AbstractStringBuilder的两者都是可变的,并且也定义了getValues方法让我们可以直接拿到value[],value实际上是个动态数组,和ArrayList的实现有很多相似的地方

注意和String的区别

4.该抽象类实现的接口

(1).CharSequence接口
public interface CharSequence{
    int length();                      //字符序列长度
    char charAt(int index);                //取得下标为index的字符
    CharSequence subSequence(int start, int end);    //得到该字符序列的一个子序列
    public String toString();            //规定了该字符序列的String版本
}

实现这个接口的类都会重写这四个方法

(2).public interface Appendable{
Appendable append(char c)             向此 Appendable 添加指定字符。
Appendable append(CharSequence csq)         向此 Appendable 添加指定的字符序列。
Appendable append(CharSequence csq, int start, int end)向此 Appendable 添加指定字符序列的子序列。

}
Appendable接口:
Appendable接口的实现类的对象能够被添加 char 序列和值。(像IO里的类就实现了这个接口)
如果某个泪的实例打算接收取自Formatter的格式化输出,那么这个类必须实现Appendable接口,
格式化主要用在文本输出方面,比如:数字,日期,金额等。 

 
原文地址:https://www.cnblogs.com/inspred/p/8531508.html