我們都知道客戶端或者設備端涉及到版本號的地方就必定會涉及到版本升級問題,這時候就需要我們比較版本號的大小,字符串類型的版本號是怎麼比較呢?傳統來說我們一般會使用compareTo 或者string轉double之後比較,這樣都會出現bug,今天我說一下一下兩種比較方式:用split根據“.”進行拆分,再分別比較每個拆分出來的字符串的大小,下面看代碼:(額外說一下,我這裏用到的版本號不含字母,所以不考慮含有字母的情況,這個可以自己做相應的修改)
public static int compare(String v1,String v2){ String [] xx=v1.split("\\."); String [] yy=v2.split("\\."); int a=0; try { for(int x=0,y=0;x<xx.length||y<yy.length;x++,y++){ int left=(x<xx.length)?Integer.parseInt(xx[x]):0; int right=(y<yy.length)?Integer.parseInt(yy[y]):0; if(left>right){ a=1; }else if(left==right){ continue; }else{ a=-1; } a=0; } } catch (Exception e) { // TODO: handle exception } return a; }
但是從性能的角度看,這種方式並不是最完美的,我們有一種類似於底層的方式,可以更好的節省性能,運行速度有所提升,廢話不多說,看代碼:
public static int compare2(String v1,String v2){ int i=0,j=0,x=0,y=0; int v1Len=v1.length(); int v2Len=v2.length(); char c; do { while(i<v1Len){//計算出V1中的點之前的數字 c=v1.charAt(i++); if(c>='0' && c<='9'){ x=x*10+(c-'0');//c-‘0’表示兩者的ASCLL差值 }else if(c=='.'){ break;//結束 }else{ //無效的字符 } } while(j<v2Len){//計算出V2中的點之前的數字 c=v2.charAt(j++); if(c>='0' && c<='9'){ y=y*10+(c-'0'); }else if(c=='.'){ break;//結束 }else{ //無效的字符 } } if(x<y){ return -1; }else if(x>y){ return 1; }else{ x=0;y=0; continue; } } while ((i<v1Len) || (j<v2Len)); return 0; }
public static void main(String[] args) { System.out.println("比較性能開始>>>>>>>>>>>>>"); String v1="0.10.20.1"; String v2="0.001.02.3"; Long startTime=System.currentTimeMillis(); for(int i=0;i<1000000;i++){ compare(v1, v2); } Long endTime=System.currentTimeMillis(); System.out.println("split方式比較100萬次用時"+(endTime-startTime)); Long startTime1=System.currentTimeMillis(); for(int i=0;i<1000000;i++){ compare2(v1, v2); } Long endTime1=System.currentTimeMillis(); System.out.println("字符char方式比較100萬次用時"+(endTime1-startTime1)); }
測試的結果如下:
比較性能開始>>>>>>>>>>>>>
split方式比較100萬次用時538
字符char方式比較100萬次用時28
如此一來,高下立判,第一次寫博客,有不對的地方還請指正