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

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10

当前回答

对于要显示基于版本号的强制更新警报的人,我有以下想法。这可能用于比较Android当前应用版本和firebase远程配置版本之间的版本。这并不是问题的确切答案,但这肯定会对某人有所帮助。

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class Main
{
  static String firebaseVersion = "2.1.3"; // or 2.1
  static String appVersion = "2.1.4";
  static List<String> firebaseVersionArray;
  static List<String> appVersionArray;
  static boolean isNeedToShowAlert = false;
  public static void main (String[]args)
  {
    System.out.println ("Hello World");
    firebaseVersionArray = new ArrayList<String>(Arrays.asList(firebaseVersion.split ("\\.")));
    appVersionArray = new ArrayList<String>(Arrays.asList(appVersion.split ("\\.")));
    if(appVersionArray.size() < firebaseVersionArray.size()) {
        appVersionArray.add("0");
    }
    if(firebaseVersionArray.size() < appVersionArray.size()) {
        firebaseVersionArray.add("0");
    }
    isNeedToShowAlert = needToShowAlert(); //Returns false
    System.out.println (isNeedToShowAlert);

  }
  static boolean needToShowAlert() {
      boolean result = false;
      for(int i = 0 ; i < appVersionArray.size() ; i++) {
          if (Integer.parseInt(appVersionArray.get(i)) == Integer.parseInt(firebaseVersionArray.get(i))) {
              continue;
          } else if (Integer.parseInt(appVersionArray.get(i)) > Integer.parseInt(firebaseVersionArray.get(i))){
             result = false;
             break;
          } else if (Integer.parseInt(appVersionArray.get(i)) < Integer.parseInt(firebaseVersionArray.get(i))) {
             result = true;
             break;  
          }
      }
      return result;
  }
}

您可以通过复制粘贴来运行此代码 https://www.onlinegdb.com/online_java_compiler

其他回答

基于https://stackoverflow.com/a/27891752/2642478

class Version(private val value: String) : Comparable<Version> {
    private val splitted by lazy { value.split("-").first().split(".").map { it.toIntOrNull() ?: 0 } }

    override fun compareTo(other: Version): Int {
        for (i in 0 until maxOf(splitted.size, other.splitted.size)) {
            val compare = splitted.getOrElse(i) { 0 }.compareTo(other.splitted.getOrElse(i) { 0 })
            if (compare != 0)
                return compare
        }
        return 0
    }
}

你可以用like:

    System.err.println(Version("1.0").compareTo( Version("1.0")))
    System.err.println(Version("1.0") < Version("1.1"))
    System.err.println(Version("1.10") > Version("1.9"))
    System.err.println(Version("1.10.1") > Version("1.10"))
    System.err.println(Version("0.0.1") < Version("1"))

@alex在Kotlin上的帖子

class Version(inputVersion: String) : Comparable<Version> {

        var version: String
            private set

        override fun compareTo(other: Version) =
            (split() to other.split()).let {(thisParts, thatParts)->
                val length = max(thisParts.size, thatParts.size)
                for (i in 0 until length) {
                    val thisPart = if (i < thisParts.size) thisParts[i].toInt() else 0
                    val thatPart = if (i < thatParts.size) thatParts[i].toInt() else 0
                    if (thisPart < thatPart) return -1
                    if (thisPart > thatPart) return 1
                }
                 0
            }

        init {
            require(inputVersion.matches("[0-9]+(\\.[0-9]+)*".toRegex())) { "Invalid version format" }
            version = inputVersion
        }
    }

    fun Version.split() = version.split(".").toTypedArray()

用法:

Version("1.2.4").compareTo(Version("0.0.5")) //return 1
public int compare(String v1, String v2) {
        v1 = v1.replaceAll("\\s", "");
        v2 = v2.replaceAll("\\s", "");
        String[] a1 = v1.split("\\.");
        String[] a2 = v2.split("\\.");
        List<String> l1 = Arrays.asList(a1);
        List<String> l2 = Arrays.asList(a2);


        int i=0;
        while(true){
            Double d1 = null;
            Double d2 = null;

            try{
                d1 = Double.parseDouble(l1.get(i));
            }catch(IndexOutOfBoundsException e){
            }

            try{
                d2 = Double.parseDouble(l2.get(i));
            }catch(IndexOutOfBoundsException e){
            }

            if (d1 != null && d2 != null) {
                if (d1.doubleValue() > d2.doubleValue()) {
                    return 1;
                } else if (d1.doubleValue() < d2.doubleValue()) {
                    return -1;
                }
            } else if (d2 == null && d1 != null) {
                if (d1.doubleValue() > 0) {
                    return 1;
                }
            } else if (d1 == null && d2 != null) {
                if (d2.doubleValue() > 0) {
                    return -1;
                }
            } else {
                break;
            }
            i++;
        }
        return 0;
    }

我喜欢@Peter Lawrey的想法,我把它扩展到更远的范围:

    /**
    * Normalize string array, 
    * Appends zeros if string from the array
    * has length smaller than the maxLen.
    **/
    private String normalize(String[] split, int maxLen){
        StringBuilder sb = new StringBuilder("");
        for(String s : split) {
            for(int i = 0; i<maxLen-s.length(); i++) sb.append('0');
            sb.append(s);
        }
        return sb.toString();
    }

    /**
    * Removes trailing zeros of the form '.00.0...00'
    * (and does not remove zeros from, say, '4.1.100')
    **/
    public String removeTrailingZeros(String s){
        int i = s.length()-1;
        int k = s.length()-1;
        while(i >= 0 && (s.charAt(i) == '.' || s.charAt(i) == '0')){
          if(s.charAt(i) == '.') k = i-1;
          i--;  
        } 
        return s.substring(0,k+1);
    }

    /**
    * Compares two versions(works for alphabets too),
    * Returns 1 if v1 > v2, returns 0 if v1 == v2,
    * and returns -1 if v1 < v2.
    **/
    public int compareVersion(String v1, String v2) {

        // Uncomment below two lines if for you, say, 4.1.0 is equal to 4.1
        // v1 = removeTrailingZeros(v1);
        // v2 = removeTrailingZeros(v2);

        String[] splitv1 = v1.split("\\.");
        String[] splitv2 = v2.split("\\.");
        int maxLen = 0;
        for(String str : splitv1) maxLen = Math.max(maxLen, str.length());
        for(String str : splitv2) maxLen = Math.max(maxLen, str.length());
        int cmp = normalize(splitv1, maxLen).compareTo(normalize(splitv2, maxLen));
        return cmp > 0 ? 1 : (cmp < 0 ? -1 : 0);
    }

希望它能帮助到别人。它通过了interviewbit和leetcode中的所有测试用例(需要取消compareVersion函数中的两行注释)。

很容易测试!

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

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