一种字符版本号转换整数方式的实现

56 阅读2分钟

背景

业务场景中有一种版本号,如1.22.13,规则是首位最大,现在需要做版本号的比较,一种方式是单独每个位置去比较的,数据保存成字符形式;还有一种方式是将版本号映射转换成整数,统一存储。由于业务的情况,对应字段一直存储的是整数,所以考虑采用第二种转换为整数的实现。如下会做具体的说明和实现介绍。

实现

首先,有些同学会想到直接去掉逗号,变成数字,显然这种处理是错误不符合要求的。比如A=3.1.1B=1.11.1。我们看到正确应该A是大于B的,但是直接去掉符号会变成B(1111)>A(311)。这里我们需要的是按逗号分隔的位置,靠左的位数字属于高位,最终转换的整数要依据此规则达到递增。我们再观察数字,可以发现这个版本号有点类似IP地址,所以参考ip地址转换整数,想到如下的实现。

  1. 定义每个版本数字不超过三位。
  2. 依上用二进制代表则是每个版本数字位置是10位(1024)。
  3. 总的版本数字位置为版本号逗号分隔的数组长度len。
  4. 从左侧转换,索引位置为i, 第1位的版本数字要左移位10*(len - 1 - 0), 第i位的为10*(len - 1 - i), 暂存结果为e
  5. 重复3步骤直到所有版本数字比较完毕,得到e累加的结果rs

详情可以参考如下的代码。

代码

包含主体代码和几个测试用例,注意加法可以和或运算等价。

    private long convert(String s) {
        String[] arr = s.split("\\.");
        if (arr.length < 1) {
            return -1;
        }

        long rs = 0;
        for (int i = 0; i < arr.length; i++) {
            int e = Integer.parseInt(arr[i]) << (10 * (arr.length - i - 1));
            rs += e;  //or rs |= e
        }
        return rs;
    }


    @Test
    public void convertTest() {
        List<String> list = Lists.newArrayList();
        list.add("1.3.1");
        list.add("1.3.33");
        list.add("1.33.33");
        
        for (String s : list) {
            System.out.println(s + "\t" + convert(s));
        }
    }

运行结果:

1.3.1	1051649
1.3.33	1051681
1.33.33	1082401

参考资料

  1. ip 地址与 int 整数的相互转换,Java 基于位运算 7 行代码实现