是否有比较版本号的标准习语?我不能直接使用String compareTo,因为我还不知道点释放的最大数量是多少。我需要比较版本,并有以下保持正确:

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10

当前回答

我自己写了一个小函数。更简单地使用列表

 public static boolean checkVersionUpdate(String olderVerison, String newVersion) {
        if (olderVerison.length() == 0 || newVersion.length() == 0) {
            return false;
        }
        List<String> newVerList = Arrays.asList(newVersion.split("\\."));
        List<String> oldVerList = Arrays.asList(olderVerison.split("\\."));

        int diff = newVerList.size() - oldVerList.size();
        List<String> newList = new ArrayList<>();
        if (diff > 0) {
            newList.addAll(oldVerList);
            for (int i = 0; i < diff; i++) {
                newList.add("0");
            }
            return examineArray(newList, newVerList, diff);
        } else if (diff < 0) {
            newList.addAll(newVerList);
            for (int i = 0; i < -diff; i++) {
                newList.add("0");
            }
            return examineArray(oldVerList, newList, diff);
        } else {
            return examineArray(oldVerList, newVerList, diff);
        }

    }

    public static boolean examineArray(List<String> oldList, List<String> newList, int diff) {
        boolean newVersionGreater = false;
        for (int i = 0; i < oldList.size(); i++) {
            if (Integer.parseInt(newList.get(i)) > Integer.parseInt(oldList.get(i))) {
                newVersionGreater = true;
                break;
            } else if (Integer.parseInt(newList.get(i)) < Integer.parseInt(oldList.get(i))) {
                newVersionGreater = false;
                break;
            } else {
                newVersionGreater = diff > 0;
            }
        }

        return newVersionGreater;
    }

其他回答

如果你的项目中已经有Jackson,你可以使用com.fasterxml.jackson.core.Version:

import com.fasterxml.jackson.core.Version;
import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class VersionTest {

    @Test
    public void shouldCompareVersion() {
        Version version1 = new Version(1, 11, 1, null, null, null);
        Version version2 = new Version(1, 12, 1, null, null, null);
        assertTrue(version1.compareTo(version2) < 0);
    }
}

也许有人会对我的解决方案感兴趣:

class Version private constructor(private val versionString: String) : Comparable<Version> {

    private val major: Int by lazy { versionString.split(".")[0].toInt() }

    private val minor: Int by lazy { versionString.split(".")[1].toInt() }

    private val patch: Int by lazy {
        val splitArray = versionString.split(".")

        if (splitArray.size == 3)
            splitArray[2].toInt()
        else
            0
    }

    override fun compareTo(other: Version): Int {
        return when {
            major > other.major -> 1
            major < other.major -> -1
            minor > other.minor -> 1
            minor < other.minor -> -1
            patch > other.patch -> 1
            patch < other.patch -> -1
            else -> 0
        }
    }

    override fun equals(other: Any?): Boolean {
        if (other == null || other !is Version) return false
        return compareTo(other) == 0
    }

    override fun hashCode(): Int {
        return major * minor * patch
    }

    companion object {
        private fun doesContainsVersion(string: String): Boolean {
            val versionArray = string.split(".")

            return versionArray.size in 2..3
                    && versionArray[0].toIntOrNull() != null
                    && versionArray[1].toIntOrNull() != null
                    && (versionArray.size == 2 || versionArray[2].toIntOrNull() != null)
        }

        fun from(string: String): Version? {
            return if (doesContainsVersion(string)) {
                Version(string)
            } else {
                null
            }
        }
    }
}

用法:

val version1 = Version.from("3.2")
val version2 = Version.from("3.2.1")
version1 <= version2

由于本页上没有答案能很好地处理混合文本,我做了自己的版本:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main {
    static double parseVersion(String v) {
        if (v.isEmpty()) {
            return 0;
        }
        Pattern p = Pattern.compile("^(\\D*)(\\d*)(\\D*)$");
        Matcher m = p.matcher(v);
        m.find();
        if (m.group(2).isEmpty()) {
            // v1.0.0.[preview]
            return -1;
        }
        double i = Integer.parseInt(m.group(2));
        if (!m.group(3).isEmpty()) {
            // v1.0.[0b]
            i -= 0.1;
        }
        return i;
    }

    public static int versionCompare(String str1, String str2) {
        String[] v1 = str1.split("\\.");
        String[] v2 = str2.split("\\.");
        int i = 0;
        for (; i < v1.length && i < v2.length; i++) {
            double iv1 = parseVersion(v1[i]);
            double iv2 = parseVersion(v2[i]);

            if (iv1 != iv2) {
                return iv1 - iv2 < 0 ? -1 : 1;
            }
        }
        if (i < v1.length) {
            // "1.0.1", "1.0"
            double iv1 = parseVersion(v1[i]);
            return iv1 < 0 ? -1 : (int) Math.ceil(iv1);
        }
        if (i < v2.length) {
            double iv2 = parseVersion(v2[i]);
            return -iv2 < 0 ? -1 : (int) Math.ceil(iv2);
        }
        return 0;
    }


    public static void main(String[] args) {
        System.out.println("versionCompare(v1.0.0, 1.0.0)");
        System.out.println(versionCompare("v1.0.0", "1.0.0")); // 0

        System.out.println("versionCompare(v1.0.0b, 1.0.0)");
        System.out.println(versionCompare("v1.0.0b", "1.0.0")); // -1

        System.out.println("versionCompare(v1.0.0.preview, 1.0.0)");
        System.out.println(versionCompare("v1.0.0.preview", "1.0.0")); // -1

        System.out.println("versionCompare(v1.0, 1.0.0)");
        System.out.println(versionCompare("v1.0", "1.0.0")); // 0

        System.out.println("versionCompare(ver1.0, 1.0.1)");
        System.out.println(versionCompare("ver1.0", "1.0.1")); // -1
    }
}

不过,在需要比较“alpha”和“beta”的情况下,它仍然不够。

public static void main(String[] args) {

    String version1 = "1.0";
    String version2 = "1.0.0";
    String[] version1_splits = version1.split("\\.");
    String[] version2_splits = version2.split("\\.");
    int length = version1_splits.length >= version2_splits.length ? version1_splits.length : version2_splits.length;
    int i=0;
    for(;i<length;i++){
        int version1_int = getValue(version1_splits,i);
        int version2_int = getValue(version2_splits,i);
        if(version1_int > version2_int){
            System.out.println("version1 > version2");
            break;
        }
        else if(version1_int < version2_int){
            System.out.println("version2 > version1");
            break;
        }
        else{
            if(i == length-1)
            System.out.println("version1 = version2");
        }
    }
}

private static int getValue(String[] version1_splits, int i) {
    int temp;
    try{
        temp = Integer.valueOf(version1_splits[i]);
    }
    catch(IndexOutOfBoundsException e){
        temp=0;
    }

    return temp;
}

用点作为分隔符对字符串进行标记,然后从左边开始并排比较整数转换。