package example.java; /** * @author 杜科 * @description 簡單動態字符串,非線程安全。採起相似buffer的設計,使其成爲一個能夠方便重用的StringBuilder * @contact AllenDuke@163.com * @date 2020/6/9 */ public class SDS implements Comparable<SDS>{ private int writePosition;//下一個要寫的下標 private int capacity;//char數組大小 private char[] chars; private int hashcode=0; public SDS(){ this.capacity=40; this.chars=new char[40]; } public SDS(int capacity){ this.capacity=capacity; this.chars=new char[capacity]; } /** *在使用sds時,儘可能設定好最大容量,以減小擴容判斷 */ public SDS append(char ch){ if(writePosition==capacity) grow(); this.chars[writePosition++]=ch; return this; } public SDS append(String s){ if((this.capacity-this.writePosition)<s.length()) grow();//先一次判斷擴容 for(int i=0;i<s.length();i++){ this.chars[writePosition++]=s.charAt(i); } // s.getChars(0, s.length(), chars, writePosition); return this; } public SDS append(SDS sds){ if((this.capacity-this.writePosition)<sds.length()) grow();//先一次判斷擴容 for(int i=0;i<sds.length();i++){ this.chars[writePosition++]=sds.charAt(i); } return this; } private void grow(){ int oldCapacity=capacity; int newCapacity=capacity<<1; char[] newChars=new char[newCapacity]; System.arraycopy(chars,0,newChars,0,oldCapacity); capacity=newCapacity; this.chars=newChars; } public char charAt(int i){ return this.chars[i]; } public SDS setCharAt(int i, char ch){ this.chars[i]=ch; return this; } public SDS clear(){ this.writePosition=0; this.hashcode=0; return this; } public int length(){ return this.writePosition; } @Override public int compareTo(SDS sds){ if(this.writePosition<sds.writePosition) return -1; if(this.writePosition>sds.writePosition) return 1; for(int i=0;i<writePosition;i++){ if(chars[i]<sds.charAt(i)) return -1; if(chars[i]>sds.charAt(i)) return 1; } return 0; } @Override public int hashCode() { if(hashcode!=0) return hashcode; for(int i=0;i<writePosition;i++) hashcode=hashcode*31+chars[i];//與String的hashcode生成方法保持一致 return hashcode; } @Override public boolean equals(Object obj) { if(this==obj) return true; if(obj.hashCode()!=this.hashcode) return false; if(!(obj instanceof SDS)) return false; SDS sds= (SDS) obj; if(sds.writePosition!=this.writePosition) return false; for(int i=0;i<this.writePosition;i++){ if(sds.charAt(i)!=this.chars[i]) return false; } return true; } @Override public String toString() { return new String(chars,0,writePosition); } }
比起StringBuilder,SDS減小了大量可有可無的運算,性能彷佛比StringBuilder好。java
簡單測試數組
package example.java; /** * @author 杜科 * @description 測試SDS可重用的性能 * @contact AllenDuke@163.com * @date 2020/6/17 */ public class SDSTest { private static int count=100000000; public static void main(String[] args) { long start=System.currentTimeMillis()/1000; testStringBuilder(); testSDS(); } public static void testStringBuilder(){ StringBuilder builder = new StringBuilder(); long time = System.currentTimeMillis(); for(int i=0;i<10000000;i++){ builder = new StringBuilder(40); builder.append("aa"); builder.append("bb"); builder.append("cc"); builder.append("dd"); builder.append("ee"); builder.toString(); } System.out.println("StringBuilder new 耗時:" + (System.currentTimeMillis() - time)); long time1 = System.currentTimeMillis(); StringBuilder builder1 = new StringBuilder(40); for(int i=0;i<10000000;i++){ builder1.delete(0, builder.length()); builder1.append("aa"); builder1.append("bb"); builder1.append("cc「); builder1.append("dd"); builder1.append("ee"); builder1.toString(); } System.out.println("StringBuilder delete 耗時:" + (System.currentTimeMillis() - time1)); long time2 = System.currentTimeMillis(); StringBuilder builder2 = new StringBuilder(40); for(int i=0;i<10000000;i++){ builder2.setLength(0); builder2.append("aa"); builder2.append("bb"); builder2.append("cc"); builder2.append("dd"); builder2.append("ee"); builder2.toString(); } System.out.println("StringBuilder setLenth=0 耗時:" + (System.currentTimeMillis() - time2)); } public static void testSDS(){ SDS sds; long time = System.currentTimeMillis(); for(int i=0;i<10000000;i++){ sds = new SDS(); sds.append("aa"); sds.append("bb"); sds.append("cc"); sds.append("dd"); sds.append("ee"); sds.toString(); } System.out.println("SDS new 耗時:" + (System.currentTimeMillis() - time)); long time2 = System.currentTimeMillis(); sds=new SDS(); for(int i=0;i<10000000;i++){ sds.clear(); sds.append("aa"); sds.append("bb"); sds.append("cc"); sds.append("dd"); sds.append("ee"); sds.toString(); } System.out.println("SDS clear 耗時:" + (System.currentTimeMillis() - time2)); } }