Develop a Java StringBuffer
According to IStringBuffer interface, make a MyStringBuffer by yourself
Step 1: IStringBuffer interface
package character; public interface IStringBuffer { public void append(String str); //Additional string public void append(char c); //Additional character public void insert(int pos,char b); //Insert character at specified position public void insert(int pos,String b); //Insert string at specified position public void delete(int start); //Delete the rest from the beginning public void delete(int start,int end); //Delete the end position-1 from the start position public void reverse(); //Reversal public int length(); //Return length }
Step 2: value and capacity
value: Used to store character arrays
Capacity:capacity
Parametric construction method: initialize value according to capacity
public MyStringBuffer(){ value = new char[capacity]; } package character; public class MyStringBuffer implements IStringBuffer{ int capacity = 16; int length = 0; char[] value; public MyStringBuffer(){ value = new char[capacity]; } @Override public void append(String str) { // TODO Auto-generated method stub } @Override public void append(char c) { // TODO Auto-generated method stub } @Override public void insert(int pos, char b) { // TODO Auto-generated method stub } @Override public void delete(int start) { // TODO Auto-generated method stub } @Override public void delete(int start, int end) { // TODO Auto-generated method stub } @Override public void reverse() { // TODO Auto-generated method stub } @Override public int length() { // TODO Auto-generated method stub return 0; } }
Step 3: Constructing method with parameters
package character; public class MyStringBuffer implements IStringBuffer{ int capacity = 16; int length = 0; char[] value; public MyStringBuffer(){ value = new char[capacity]; } //Parametric construction method public MyStringBuffer(String str){ if(null!=str) value =str.toCharArray(); length = value.length; if(capacity<value.length) capacity = value.length*2; } @Override public void append(String str) { // TODO Auto-generated method stub } @Override public void append(char c) { // TODO Auto-generated method stub } @Override public void insert(int pos, char b) { } @Override public void delete(int start) { // TODO Auto-generated method stub } @Override public void delete(int start, int end) { // TODO Auto-generated method stub } @Override public void reverse() { // TODO Auto-generated method stub } @Override public int length() { // TODO Auto-generated method stub return length; } @Override public void insert(int pos, String b) { } }
Step 4: reverse
package character; public class MyStringBuffer implements IStringBuffer { int capacity = 16; int length = 0; char[] value; public MyStringBuffer() { value = new char[capacity]; } // Parametric construction method public MyStringBuffer(String str) { this(); if (null == str) return; if (capacity < str.length()) { capacity = value.length * 2; value = new char[capacity]; } if (capacity >= str.length()) System.arraycopy(str.toCharArray(), 0, value, 0, str.length()); length = str.length(); } @Override public void reverse() { for (int i = 0; i < length / 2; i++) { char temp = value[i]; value[i] = value[length - i - 1]; value[length - i - 1] = temp; } } @Override public void append(String str) { // TODO Auto-generated method stub } @Override public void append(char c) { // TODO Auto-generated method stub } @Override public void insert(int pos, char b) { // TODO Auto-generated method stub } @Override public void insert(int pos, String b) { // TODO Auto-generated method stub } @Override public void delete(int start) { // TODO Auto-generated method stub } @Override public void delete(int start, int end) { // TODO Auto-generated method stub } @Override public int length() { // TODO Auto-generated method stub return length; } public String toString() { char[] realValue = new char[length]; System.arraycopy(value, 0, realValue, 0, length); return new String(realValue); } public static void main(String[] args) { MyStringBuffer sb = new MyStringBuffer("there light"); sb.reverse(); System.out.println(sb); } }
Step 5: Insert insert and append
Boundary Conditions Judgment
Before insertion, some boundary conditions must be judged first. For example, if the insertion position is legal, whether the insertion string is empty
Capacity expansion
- It is necessary to determine whether expansion is needed. If the total length of the inserted string plus the existing content exceeds the capacity, then expansion is required.
- The length of the array is fixed and can not be changed. The array itself does not support expansion. We use flexible ways to solve this problem.
- A new capacity is calculated based on the length of the string to be inserted and the length of the existing content. Then, according to this capacity, a new array is created, and then the contents of the original array are copied into the new array. And let the value reference point to the new array, so as to achieve the effect of expansion.
Insert string
- Find the position where you want to insert the string. Start from this position, consider the original data as two segments, and move the second half backward by a distance, which is exactly the length of the insertion string.
- Then insert the data you want to insert into the right place where you moved it out.
Modify the value of length
Finally, the length value is modified by adding the original value plus the length of the insertion string.
insert(int, char)
The parameter is the insert method of characters, which is implemented by calling insert(int, String).
append
Addition is insertion at the last place. Therefore, the insert method can be directly invoked without the need for a separate development method to achieve the final insert effect.
package character; public class MyStringBuffer implements IStringBuffer{ int capacity = 16; int length = 0; char[] value; public MyStringBuffer(){ value = new char[capacity]; } //Parametric construction method public MyStringBuffer(String str){ this(); if(null==str) return; if(capacity<str.length()){ capacity = value.length*2; value=new char[capacity]; } if(capacity>=str.length()) System.arraycopy(str.toCharArray(), 0, value, 0, str.length()); length = str.length(); } @Override public void append(String str) { insert(length,str); } @Override public void append(char c) { append(String.valueOf(c)); } @Override public void insert(int pos, char b) { insert(pos,String.valueOf(b)); } @Override public void delete(int start) { // TODO Auto-generated method stub } @Override public void delete(int start, int end) { // TODO Auto-generated method stub } @Override public void reverse() { for (int i = 0; i < length/2; i++) { char temp = value[i]; value[i] = value[length-i-1]; value[length-i-1] = temp; } } @Override public int length() { // TODO Auto-generated method stub return length; } @Override public void insert(int pos, String b) { //Boundary Conditions Judgment if(pos<0) return; if(pos>length) return; if(null==b) return; //Capacity expansion while(length+b.length()>capacity){ capacity = (int) ((length+b.length())*1.5f); char[] newValue = new char[capacity]; System.arraycopy(value, 0, newValue, 0, length); value = newValue; } char[] cs = b.toCharArray(); //Move back the existing data first System.arraycopy(value, pos, value,pos+ cs.length, length-pos); //Insert the data to be inserted into the specified location System.arraycopy(cs, 0, value, pos, cs.length); length = length+cs.length; } public String toString(){ char[] realValue = new char[length]; System.arraycopy(value, 0, realValue, 0, length); return new String(realValue); } public static void main(String[] args) { MyStringBuffer sb = new MyStringBuffer("there light"); System.out.println(sb); sb.insert(0, "let "); System.out.println(sb); sb.insert(10, "be "); System.out.println(sb); sb.insert(0, "God Say:"); System.out.println(sb); sb.append("!"); System.out.println(sb); sb.append('?'); System.out.println(sb); sb.reverse(); System.out.println(sb); } }
Step 6: Delete delete
package character; public class MyStringBuffer implements IStringBuffer{ int capacity = 16; int length = 0; char[] value; public MyStringBuffer(){ value = new char[capacity]; } //Parametric construction method public MyStringBuffer(String str){ this(); if(null==str) return; if(capacity<str.length()){ capacity = value.length*2; value=new char[capacity]; } if(capacity>=str.length()) System.arraycopy(str.toCharArray(), 0, value, 0, str.length()); length = str.length(); } @Override public void append(String str) { insert(length,str); } @Override public void append(char c) { append(String.valueOf(c)); } @Override public void insert(int pos, char b) { insert(pos,String.valueOf(b)); } @Override public void delete(int start) { delete(start,length); } @Override public void delete(int start, int end) { //Boundary Conditions Judgment if(start<0) return; if(start>length) return; if(end<0) return; if(end>length) return; if(start>=end) return; System.arraycopy(value, end, value, start, length- end); length-=end-start; } @Override public void reverse() { for (int i = 0; i < length/2; i++) { char temp = value[i]; value[i] = value[length-i-1]; value[length-i-1] = temp; } } @Override public int length() { // TODO Auto-generated method stub return length; } @Override public void insert(int pos, String b) { //Boundary Conditions Judgment if(pos<0) return; if(pos>length) return; if(null==b) return; //Capacity expansion while(length+b.length()>capacity){ capacity = (int) ((length+b.length())*1.5f); char[] newValue = new char[capacity]; System.arraycopy(value, 0, newValue, 0, length); value = newValue; } char[] cs = b.toCharArray(); //Move back the existing data first System.arraycopy(value, pos, value,pos+ cs.length, length-pos); //Insert the data to be inserted into the specified location System.arraycopy(cs, 0, value, pos, cs.length); length = length+cs.length; } public String toString(){ char[] realValue = new char[length]; System.arraycopy(value, 0, realValue, 0, length); return new String(realValue); } public static void main(String[] args) { MyStringBuffer sb = new MyStringBuffer("there light"); System.out.println(sb); sb.insert(0, "let "); System.out.println(sb); sb.insert(10, "be "); System.out.println(sb); sb.insert(0, "God Say:"); System.out.println(sb); sb.append("!"); System.out.println(sb); sb.append('?'); System.out.println(sb); sb.reverse(); System.out.println(sb); sb.reverse(); System.out.println(sb); sb.delete(0,4); System.out.println(sb); sb.delete(4); System.out.println(sb); } }
Practice: performance comparison
Compare the performance of Java's StringBuffer with the MyStringBuffer we developed ourselves.
Reference comparison scheme:
- Generate Random Strings of Length 10
- Use StringBuffer to add 1,000,000 statistical times
- Use MyStringBuffer to add 1,000,000 statistical times