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

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10

当前回答

使用Java 9自带的Version类

import java.util.*;
import java.lang.module.ModuleDescriptor.Version;
class Main {
  public static void main(String[] args) {
    var versions = Arrays.asList(
      "1.0.2",
      "1.0.0-beta.2",
      "1.0.0",
      "1.0.0-beta",
      "1.0.0-alpha.12",
      "1.0.0-beta.11",
      "1.0.1",
      "1.0.11",
      "1.0.0-rc.1",
      "1.0.0-alpha.1",
      "1.1.0",
      "1.0.0-alpha.beta",
      "1.11.0",
      "1.0.0-alpha.12.ab-c",
      "0.0.1",
      "1.2.1",
      "1.0.0-alpha",
      "1.0.0.1",  // Also works with a number of sections different than 3
      "1.0.0.2",
      "2",
      "10",
      "1.0.0.10"
    );
    versions.stream()
      .map(Version::parse)
      .sorted()
      .forEach(System.out::println);
  }
}

在网上试试!

输出:

0.0.1
1.0.0-alpha
1.0.0-alpha.1
1.0.0-alpha.12
1.0.0-alpha.12.ab-c
1.0.0-alpha.beta
1.0.0-beta
1.0.0-beta.2
1.0.0-beta.11
1.0.0-rc.1
1.0.0
1.0.0.1
1.0.0.2
1.0.0.10
1.0.1
1.0.2
1.0.11
1.1.0
1.2.1
1.11.0
2
10

其他回答

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;
}

此代码尝试解决这种类型的比较版本。

大多数版本说明符,如>= 1.0,都是不言自明的。的 说明符~>具有特殊含义,最好通过示例来说明。~> 2.0.3是 与>= 2.0.3和< 2.1相同。~> 2.1与>= 2.1相同,且< 3.0.

public static boolean apply(String cmpDeviceVersion, String reqDeviceVersion)
{
    Boolean equal           = !cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") &&
                              !cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<=") &&
                              !cmpDeviceVersion.contains("~>");

    Boolean between         = cmpDeviceVersion.contains("~>");
    Boolean higher          = cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") && !cmpDeviceVersion.contains("~>");
    Boolean higherOrEqual   = cmpDeviceVersion.contains(">=");

    Boolean less            = cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<=");
    Boolean lessOrEqual     = cmpDeviceVersion.contains("<=");

    cmpDeviceVersion        = cmpDeviceVersion.replaceAll("[<>=~]", "");
    cmpDeviceVersion        = cmpDeviceVersion.trim();

    String[] version        = cmpDeviceVersion.split("\\.");
    String[] reqVersion     = reqDeviceVersion.split("\\.");

    if(equal)
    {
        return isEqual(version, reqVersion);
    }
    else if(between)
    {
        return isBetween(version, reqVersion);
    }
    else if(higher)
    {
        return isHigher(version, reqVersion);
    }
    else if(higherOrEqual)
    {
        return isEqual(version, reqVersion) || isHigher(version, reqVersion);
    }
    else if(less)
    {
        return isLess(version, reqVersion);
    }
    else if(lessOrEqual)
    {
        return isEqual(version, reqVersion) || isLess(version, reqVersion);
    }

    return false;
}

private static boolean isEqual(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strVersion.equals(strReqVersion);
}

private static boolean isHigher(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strReqVersion.compareTo(strVersion) > 0;
}

private static boolean isLess(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strReqVersion.compareTo(strVersion) < 0;
}

private static boolean isBetween(String[] version, String[] reqVersion)
{
    return (isEqual(version, reqVersion) || isHigher(version, reqVersion)) &&
            isLess(getNextVersion(version), reqVersion);
}

private static String[] getNextVersion(String[] version)
{
    String[] nextVersion = new String[version.length];
    for(int i = version.length - 1; i >= 0 ; i--)
    {
        if(i == version.length - 1)
        {
            nextVersion[i] = "0";
        }
        else if((i == version.length - 2) && NumberUtils.isNumber(version[i]))
        {
            nextVersion[i] = String.valueOf(NumberUtils.toInt(version[i]) + 1);
        }
        else
        {
            nextVersion[i] = version[i];
        }
    }
    return nextVersion;
}

最好的方法是重用现有代码, 使用Maven的ComparableVersion类

优点:

Apache许可证,版本2.0, 测试, 在多个项目中使用(复制),如spring-security-core, jboss等 多个特性 它已经是java.lang。可比的了 只是复制粘贴一个类,没有第三方依赖

不要包含对maven-artifact的依赖项,因为那会拉动各种传递依赖项

这篇旧文章的另一个解决方案(对那些可能有帮助的人来说):

public class Version implements Comparable<Version> {

    private String version;

    public final String get() {
        return this.version;
    }

    public Version(String version) {
        if(version == null)
            throw new IllegalArgumentException("Version can not be null");
        if(!version.matches("[0-9]+(\\.[0-9]+)*"))
            throw new IllegalArgumentException("Invalid version format");
        this.version = version;
    }

    @Override public int compareTo(Version that) {
        if(that == null)
            return 1;
        String[] thisParts = this.get().split("\\.");
        String[] thatParts = that.get().split("\\.");
        int length = Math.max(thisParts.length, thatParts.length);
        for(int i = 0; i < length; i++) {
            int thisPart = i < thisParts.length ?
                Integer.parseInt(thisParts[i]) : 0;
            int thatPart = i < thatParts.length ?
                Integer.parseInt(thatParts[i]) : 0;
            if(thisPart < thatPart)
                return -1;
            if(thisPart > thatPart)
                return 1;
        }
        return 0;
    }

    @Override public boolean equals(Object that) {
        if(this == that)
            return true;
        if(that == null)
            return false;
        if(this.getClass() != that.getClass())
            return false;
        return this.compareTo((Version) that) == 0;
    }

}

Version a = new Version("1.1");
Version b = new Version("1.1.1");
a.compareTo(b) // return -1 (a<b)
a.equals(b)    // return false

Version a = new Version("2.0");
Version b = new Version("1.9.9");
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false

Version a = new Version("1.0");
Version b = new Version("1");
a.compareTo(b) // return 0 (a=b)
a.equals(b)    // return true

Version a = new Version("1");
Version b = null;
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false

List<Version> versions = new ArrayList<Version>();
versions.add(new Version("2"));
versions.add(new Version("1.0.5"));
versions.add(new Version("1.01.0"));
versions.add(new Version("1.00.1"));
Collections.min(versions).get() // return min version
Collections.max(versions).get() // return max version

// WARNING
Version a = new Version("2.06");
Version b = new Version("2.060");
a.equals(b)    // return false

编辑:

@daiscog:谢谢你的评论,这段代码是为Android平台开发的,由谷歌推荐,方法“匹配”检查整个字符串,不像Java使用监管模式。(Android文档- JAVA文档)

想知道为什么每个人都假设版本只由整数组成-在我的情况下,它不是。

为什么要重新发明轮子(假设版本遵循Semver标准)

首先通过Maven安装https://github.com/vdurmont/semver4j

然后使用这个库

Semver sem = new Semver("1.2.3");
sem.isGreaterThan("1.2.2"); // true