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

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10

当前回答

我写了一个小的Java/Android库来比较版本号:https://github.com/G00fY2/version-compare

它的基本功能是:

  public int compareVersions(String versionA, String versionB) {
    String[] versionTokensA = versionA.split("\\.");
    String[] versionTokensB = versionB.split("\\.");
    List<Integer> versionNumbersA = new ArrayList<>();
    List<Integer> versionNumbersB = new ArrayList<>();

    for (String versionToken : versionTokensA) {
      versionNumbersA.add(Integer.parseInt(versionToken));
    }
    for (String versionToken : versionTokensB) {
      versionNumbersB.add(Integer.parseInt(versionToken));
    }

    final int versionASize = versionNumbersA.size();
    final int versionBSize = versionNumbersB.size();
    int maxSize = Math.max(versionASize, versionBSize);

    for (int i = 0; i < maxSize; i++) {
      if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return 1;
      } else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return -1;
      }
    }
    return 0;
  }

这个代码片段不提供任何错误检查或处理。除此之外,我的库还支持像“1.2-rc”>“1.2-beta”这样的后缀。

其他回答

使用Maven真的很简单:

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;

DefaultArtifactVersion minVersion = new DefaultArtifactVersion("1.0.1");
DefaultArtifactVersion maxVersion = new DefaultArtifactVersion("1.10");

DefaultArtifactVersion version = new DefaultArtifactVersion("1.11");

if (version.compareTo(minVersion) < 0 || version.compareTo(maxVersion) > 0) {
    System.out.println("Sorry, your version is unsupported");
}

您可以从这个页面获得Maven Artifact的正确依赖项字符串:

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.0.3</version>
</dependency>

科特林:

@kotlin.jvm.Throws(InvalidParameterException::class)
fun String.versionCompare(remoteVersion: String?): Int {
    val remote = remoteVersion?.splitToSequence(".")?.toList() ?: return 1
    val local = this.splitToSequence(".").toList()

    if(local.filter { it.toIntOrNull() != null }.size != local.size) throw InvalidParameterException("version invalid: $this")
    if(remote.filter { it.toIntOrNull() != null }.size != remote.size) throw InvalidParameterException("version invalid: $remoteVersion")

    val totalRange = 0 until kotlin.math.max(local.size, remote.size)
    for (i in totalRange) {
        if (i < remote.size && i < local.size) {
            val result = local[i].compareTo(remote[i])
            if (result != 0) return result
        } else (
            return local.size.compareTo(remote.size)
        )
    }
    return 0
}

我创建了一个简单的实用程序,使用语义版本约定在Android平台上比较版本。所以它只适用于X.Y.Z (Major.Minor.Patch)格式的字符串,其中X、Y和Z是非负整数。你可以在我的GitHub上找到它。

方法version . compareversions (String v1, String v2)比较两个版本字符串。如果版本相等则返回0,如果版本v1在版本v2之前则返回1,如果版本v1在版本v2之后则返回-1,如果版本格式无效则返回-2。

public static int compareVersions(String version1, String version2){

    String[] levels1 = version1.split("\\.");
    String[] levels2 = version2.split("\\.");

    int length = Math.max(levels1.length, levels2.length);
    for (int i = 0; i < length; i++){
        Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0;
        Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0;
        int compare = v1.compareTo(v2);
        if (compare != 0){
            return compare;
        }
    }

    return 0;
}

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

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”的情况下,它仍然不够。