String.compareTo()方法用于版本号比较的坑

来源:互联网 发布:centos macaddr 编辑:程序博客网 时间:2024/05/22 15:41

  最近项目中需要比较客户端版本,项目之初使用String.compareTo()方法进行版本比较,客户端版本如:8.2.3,各级版本号都为数字且以’.’分割,当某一级别版本号大于等于10时,String.compareTo()方法返回错误。

一、String.compareTo()比较版本号

  通过String.compareTo()比较不同的版本号,结果如下:

public class Test {    public static void main(String[] args) {        System.out.println("\"8.2.3\".compareTo(\"8.2.3\") : " + "8.2.3".compareTo("8.2.3"));        System.out.println("\"8.2.3\".compareTo(\"8.7.3\") : " + "8.2.3".compareTo("8.7.3"));        System.out.println("\"8.2.3\".compareTo(\"8.1.1\") : " + "8.2.3".compareTo("8.1.1"));        System.out.println("\"8.2.3\".compareTo(\"8.2.15\") : " + "8.2.3".compareTo("8.2.15"));        System.out.println("\"8.2.3\".compareTo(\"8.2.a\") : " + "8.2.3".compareTo("8.2.a"));        System.out.println("\"8.2.3\".compareTo(\"8.2.1.236\") : " + "8.2.3".compareTo("8.2.1.236"));        System.out.println("\"8.2.3\".compareTo(\"8.8.1.236\") : " + "8.2.3".compareTo("8.8.1.236"));        System.out.println("\"8.2.3\".compareTo(\"9.4\") : " + "8.2.3".compareTo("9.4"));        System.out.println("\"8.2.3\".compareTo(\"6.4\") : " + "8.2.3".compareTo("6.4"));    }}结果:"8.2.3".compareTo("8.2.3") : 0"8.2.3".compareTo("8.7.3") : -5"8.2.3".compareTo("8.1.1") : 1"8.2.3".compareTo("8.2.15") : 2"8.2.3".compareTo("8.2.a") : -46"8.2.3".compareTo("8.2.1.236") : 2"8.2.3".compareTo("8.8.1.236") : -6"8.2.3".compareTo("9.4") : -1"8.2.3".compareTo("6.4") : 2

  以上大部分比较结果正确,但是版本号8.2.3与8.2.15的比较结果出现错误,8.2.3的版本应该比8.2.15的版本小。

  String.compareTo()源码如下,该方法比较逻辑为:按字符比较两个字符串,返回前k(两字符串中较短字符串的长度)个字符中第一个不同字符的差值,如果前k个字符都相同,则返回两个字符串的长度差值。  

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {    /** The value is used for character storage. */    private final char value[];...        public int compareTo(String anotherString) {        int len1 = value.length;        int len2 = anotherString.value.length;        int lim = Math.min(len1, len2);        char v1[] = value;        char v2[] = anotherString.value;        int k = 0;        while (k < lim) {            char c1 = v1[k];            char c2 = v2[k];            if (c1 != c2) {                return c1 - c2;            }            k++;        }        return len1 - len2;    }...}

二、正确的版本号比较方法

  String.compareTo()方法适用于按字符比较的场景,不适用于版本号比较。我们使用到的客户端版本都是数字加分隔符(”.”)组合的,正确的方式应该按分隔符将版本号切分为各级版本,然后按级别比较版本号,如下:

public class Test {    public static void main(String[] args) {        Test test = new Test();        System.out.println("compare(\"8.2.3\", \"8.2.3\") : " + test.compare("8.2.3", "8.2.3"));        System.out.println("compare(\"8.2.3\", \"8.7.3\") : " + test.compare("8.2.3","8.7.3"));        System.out.println("compare(\"8.2.3\", \"8.1.1\") : " + test.compare("8.2.3","8.1.1"));        System.out.println("compare(\"8.2.3\", \"8.2.15\") : " + test.compare("8.2.3","8.2.15"));        System.out.println("compare(\"8.2.3\", \"8.2.1.236\") : " + test.compare("8.2.3","8.2.1.236"));        System.out.println("compare(\"8.2.3\", \"8.8.1.236\") : " + test.compare("8.2.3","8.8.1.236"));        System.out.println("compare(\"8.2.3\", \"9.4\") : " + test.compare("8.2.3","9.4"));        System.out.println("compare(\"8.2.3\", \"6.4\") : " + test.compare("8.2.3","6.4"));    }    public int compare(String v1, String v2) {        if(StringUtils.isBlank(v1) && StringUtils.isBlank(v2)) {            return 0;        } else if(StringUtils.isBlank(v1)) {            return -1;        } else if(StringUtils.isBlank(v2)) {            return 1;        }        int [] varr1 = getVersionArray(v1);        int [] varr2 = getVersionArray(v2);        int lim = Math.min(varr1.length, varr2.length);        int k = 0;        while(k < lim) {            if(varr1[k] == varr2[k]) {                k ++;                continue;            }            return varr1[k] > varr2[k] ? 1 : -1;        }        if(varr1.length == varr2.length) {            return 0;        }        return varr1.length > varr2.length ? 1 : -1;    }    public int [] getVersionArray(String v) {        String [] sarray = StringUtils.split(v, ".");        int [] varray = new int[sarray.length];        int k = 0;        while (k < sarray.length) {            varray[k] = Integer.parseInt(sarray[k]);            k ++;        }        return varray;    }}结果:compare("8.2.3", "8.2.3") : 0compare("8.2.3", "8.7.3") : -1compare("8.2.3", "8.1.1") : 1compare("8.2.3", "8.2.15") : -1compare("8.2.3", "8.2.1.236") : 1compare("8.2.3", "8.8.1.236") : -1compare("8.2.3", "9.4") : -1compare("8.2.3", "6.4") : 1
原创粉丝点击