自己动手写StringBulder
继上一篇自己动手写Java String类之后,今晚10点钟下班,感觉稍早,于是手痒痒就想自己动手来写StringBulder,毕竟程序员啥都讲究自己动手才能丰衣足食嘛!StringBuilder与String类的区别是String的变量内容是放在final char[]里面的,而StringBuilder是放在char[]里面的,听说String用到了常量池。以下为自己改版过后的StringBuilder,它实现了Serializable,CharSequence接口。JDK的StringBuilder除了实现这俩接口之外,还继承了AbstractStringBuilder抽象类,由于AbstractStringBuilder是在java.lang包里面,权限是default,学过Java的同学都知道默认的权限,其他包是无法继承的,所以MyStringBuilder就不继承AbstractStringBuilder了。以下为自己动手写MyStringBuilder。
import java.io.Serializable; import java.util.Arrays; public class MyStringBuilder implements Serializable, CharSequence{ private static final long serialVersionUID = 1L; private char[] value; private int count; public MyStringBuilder() { this(16); } public MyStringBuilder(CharSequence seq) { } public MyStringBuilder(int capacity) { value = new char[capacity]; } public MyStringBuilder(String str) { value = new char[str.length()]; for(int i = 0; i < value.length; i++) { value[i] = str.charAt(i); } count = str.length(); } @Override public int length() { return count; } @Override public char charAt(int index) { //判断下标是否越界 if(index < 0 || index > count) { throw new StringIndexOutOfBoundsException(index); } //返回数组中小标为index的元素 return value[index]; } @Override public CharSequence subSequence(int start, int end) { // TODO Auto-generated method stub return null; } public MyStringBuilder append(boolean b){ if(b) { //b为true //1.为value数组扩容 value = Arrays.copyOf(value, count+4); //.2给value赋值 value[count++] = 't'; value[count++] = 'r'; value[count++] = 'u'; value[count++] = 'e'; } else { //b为false //1.为value数组扩容 value = Arrays.copyOf(value, count+5); //.2给value赋值 value[count++] = 'f'; value[count++] = 'a'; value[count++] = 'l'; value[count++] = 's'; value[count++] = 'e'; } return this; } @Override public String toString() { return new String(value); } public MyStringBuilder append(char c) { //1.给value数组扩容 value = Arrays.copyOf(value, count+1); //2.给value赋值 value[count++] = c; //返回MyStringBuilder本身,供方法链调用 return this; } public MyStringBuilder append(char[] str) { char[] newChar = new char[count+str.length]; //创建一个新数组,容纳新老字符 System.arraycopy(value, 0, newChar, 0, count); //将原数组的值塞进新数组的前半段 System.arraycopy(str, 0, newChar, count, str.length);//将要拼接的数组的值塞进新数组的后半段 value = Arrays.copyOf(newChar, newChar.length); //原来的value数组扩容 count = value.length; return this; } public MyStringBuilder append(String string) { if(string == null) { //如果对象为空,则返回"null"字符串 return appendNull(); } //1.先对value扩容 value = Arrays.copyOf(value, count+string.length()); //2.调用String类的.getChars方法,将字符从此字符串复制到value字符数组。 string.getChars(0, string.length(), value, count); //3.count长度增加 count += string.length(); return this; } private MyStringBuilder appendNull() { value = Arrays.copyOf(value, count+4); value[count++] = 'n'; value[count++] = 'u'; value[count++] = 'l'; value[count++] = 'l'; return this; } public MyStringBuilder append(float f) { /** * JDK是调用该类来完成转化的,FloatingDecimal.appendTo(f,this); */ String str = String.valueOf(f); return this.append(str); } public MyStringBuilder append(double d) { String str = String.valueOf(d); return this.append(str); } public MyStringBuilder append(Object obj) { if(obj == null) { return appendNull(); } return append(obj.toString()); } public MyStringBuilder deleteCharAt(int index) { if(index < 0 || index > count) { throw new StringIndexOutOfBoundsException(index); } System.arraycopy(value, index+1, value, index, count-index-1); count--; return this; } /** * 将字符数组倒置 * @return value 倒置后的字符数组 */ public MyStringBuilder reverse() { int n = count-1; int i = 0; //JDK使用的倒置算法比我的效率高,暂时读不懂它的代码 while(i < count/2) { char cj = value[i]; //一边从头开始 char ck = value[n-i]; //一遍从尾开始 //两个位置的元素相互交换里面的内容 value[i] = ck; value[n-i] = cj; i++; } return this; } }
上诉只提供了StringBuilder常用的方法,并没用完全实现StringBuilder的全部功能,同时apend()的重载方法有很多,这里只给出了一些比较常见的参数,如:append(String str),append(char[] chars),append(boolean b),append(Object obj);等。当然了,我的字符串倒置reverse()估计效率也没用JDK提供的高,不过功能完成实现出来了就行了!
下面为测试StringBuilder和MyStringBuilder的代码:
public class TestMyStringBuilder { public static void main(String[] args) { char[] chars = new char[4]; chars[0] = 'J'; chars[1] = 'a'; chars[2] = 'v'; chars[3] = 'a'; String nullStr = null; Student stu = new Student("1","22","男"); Student stuNull = null; StringBuilder sb = new StringBuilder(""); System.out.println("JDK提供的StringBuilder:"); System.out.println(sb.append(true).append(' ') .append(false).append(chars).append(nullStr).append("HelloJava") .append(3.141592653f).append(10086.11).append(stu).append(stuNull) .deleteCharAt(10).reverse()); System.out.println("长度:" + sb.length()); System.out.println("测试charAt:第10个字符" + sb.charAt(10)+",第20个字符:" + sb.charAt(20)); MyStringBuilder sb1 = new MyStringBuilder(""); System.out.println("自己实现的StringBuilder:"); System.out.println(sb1.append(true).append(' ') .append(false).append(chars).append(nullStr).append("HelloJava") .append(3.141592653f).append(10086.11).append(stu).append(stuNull) .deleteCharAt(10).reverse()); System.out.println("长度:" + sb1.length()); System.out.println("测试charAt:第10个字符" + sb1.charAt(10)+",第20个字符:" + sb1.charAt(20)); } }
以下为输出内容:
JDK提供的StringBuilder: llun]男=xes ,22=ega ,1=di[ tnedutS11.680017295141.3avaJolleHllunavaeslaf eurt 长度:76 测试charAt:第10个字符 ,第20个字符:1 自己实现的StringBuilder: llun]男=xes ,22=ega ,1=di[ tnedutS11.608017295141.3avaJolleHllunavaeslaf eurtl 长度:76 测试charAt:第10个字符 ,第20个字符:1
上一篇: php实现用于删除整个目录的递归函数
下一篇: 人脸识别