是否有比较版本号的标准习语?我不能直接使用String compareTo,因为我还不知道点释放的最大数量是多少。我需要比较版本,并有以下保持正确:
1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10
是否有比较版本号的标准习语?我不能直接使用String compareTo,因为我还不知道点释放的最大数量是多少。我需要比较版本,并有以下保持正确:
1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10
当前回答
我现在就做了,然后问自己,这对吗?因为我从来没有找到过比我的更干净的解决方案
你只需要像下面这样拆分字符串版本("1.0.0"):
userVersion.split("\\.")
那么你将得到:{"1","0","0"}
现在,用我做过的方法
isUpdateAvailable(userVersion.split("\\."), latestVersionSplit.split("\\."));
方法:
/**
* Compare two versions
*
* @param userVersionSplit - User string array with major, minor and patch version from user (exemple: {"5", "2", "70"})
* @param latestVersionSplit - Latest string array with major, minor and patch version from api (example: {"5", "2", "71"})
* @return true if user version is smaller than latest version
*/
public static boolean isUpdateAvailable(String[] userVersionSplit, String[] latestVersionSplit) {
try {
int majorUserVersion = Integer.parseInt(userVersionSplit[0]);
int minorUserVersion = Integer.parseInt(userVersionSplit[1]);
int patchUserVersion = Integer.parseInt(userVersionSplit[2]);
int majorLatestVersion = Integer.parseInt(latestVersionSplit[0]);
int minorLatestVersion = Integer.parseInt(latestVersionSplit[1]);
int patchLatestVersion = Integer.parseInt(latestVersionSplit[2]);
if (majorUserVersion <= majorLatestVersion) {
if (majorUserVersion < majorLatestVersion) {
return true;
} else {
if (minorUserVersion <= minorLatestVersion) {
if (minorUserVersion < minorLatestVersion) {
return true;
} else {
return patchUserVersion < patchLatestVersion;
}
}
}
}
} catch (Exception ignored) {
// Will be throw only if the versions pattern is different from "x.x.x" format
// Will return false at the end
}
return false;
}
等待任何反馈:)
其他回答
我自己写了一个小函数。更简单地使用列表
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;
}
我创建了一个简单的实用程序,使用语义版本约定在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 class VersionComparator {
/* loop through both version strings
* then loop through the inner string to computer the val of the int
* for each integer read, do num*10+<integer read>
* and stop when stumbling upon '.'
* When '.' is encountered...
* see if '.' is encountered for both strings
* if it is then compare num1 and num2
* if num1 == num2... iterate over p1++, p2++
* else return (num1 > num2) ? 1 : -1
* If both the string end then compare(num1, num2) return 0, 1, -1
* else loop through the longer string and
* verify if it only has trailing zeros
* If it only has trailing zeros then return 0
* else it is greater than the other string
*/
public static int compareVersions(String v1, String v2) {
int num1 = 0;
int num2 = 0;
int p1 = 0;
int p2 = 0;
while (p1 < v1.length() && p2 < v2.length()) {
num1 = Integer.parseInt(v1.charAt(p1) + "");
num2 = Integer.parseInt(v2.charAt(p2) + "");
p1++;
p2++;
while (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) != '.' && v2.charAt(p2) != '.') {
if (p1 < v1.length()) num1 = num1 * 10 + Integer.parseInt(v1.charAt(p1) + "");
if (p2 < v2.length()) num2 = num2 * 10 + Integer.parseInt(v2.charAt(p2) + "");
p1++;
p2++;
}
if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.' && v2.charAt(p2) == '.') {
if ((num1 ^ num2) == 0) {
p1++;
p2++;
}
else return (num1 > num2) ? 1 : -1;
}
else if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.') return -1;
else if (p1 < v1.length() && p2 < v2.length() && v2.charAt(p2) == '.') return 1;
}
if (p1 == v1.length() && p2 == v2.length()) {
if ((num1 ^ num2) == 0) return 0;
else return (num1 > num2) ? 1 : -1;
}
else if (p1 == v1.length()) {
if ((num1 ^ num2) == 0) {
while (p2 < v2.length()) {
if (v2.charAt(p2) != '.' && v2.charAt(p2) != '0') return -1;
p2++;
}
return 0;
}
else return (num1 > num2) ? 1 : -1;
}
else {
if ((num1 ^ num2) == 0) {
while (p1 < v1.length()) {
if (v1.charAt(p1) != '.' && v1.charAt(p1) != '0') return 1;
p1++;
}
return 0;
}
else return (num1 > num2) ? 1 : -1;
}
}
public static void main(String[] args) {
System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
System.out.println(compareVersions("11.21.1.0.0.1.0", "11.23") ^ -1);
System.out.println(compareVersions("11.23", "11.23.0.0.0.1.0") ^ -1);
System.out.println(compareVersions("11.2", "11.23") ^ -1);
System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
System.out.println(compareVersions("1.21.1.0.0.1.0", "2.23") ^ -1);
System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
System.out.println(compareVersions("11.23.0.0.0.0.0", "11.23") ^ 0);
System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
System.out.println(compareVersions("1.5.1.3", "1.5.1.3.0") ^ 0);
System.out.println(compareVersions("1.5.1.4", "1.5.1.3.0") ^ 1);
System.out.println(compareVersions("1.2.1.3", "1.5.1.3.0") ^ -1);
System.out.println(compareVersions("1.2.1.3", "1.22.1.3.0") ^ -1);
System.out.println(compareVersions("1.222.1.3", "1.22.1.3.0") ^ 1);
}
}
我现在就做了,然后问自己,这对吗?因为我从来没有找到过比我的更干净的解决方案
你只需要像下面这样拆分字符串版本("1.0.0"):
userVersion.split("\\.")
那么你将得到:{"1","0","0"}
现在,用我做过的方法
isUpdateAvailable(userVersion.split("\\."), latestVersionSplit.split("\\."));
方法:
/**
* Compare two versions
*
* @param userVersionSplit - User string array with major, minor and patch version from user (exemple: {"5", "2", "70"})
* @param latestVersionSplit - Latest string array with major, minor and patch version from api (example: {"5", "2", "71"})
* @return true if user version is smaller than latest version
*/
public static boolean isUpdateAvailable(String[] userVersionSplit, String[] latestVersionSplit) {
try {
int majorUserVersion = Integer.parseInt(userVersionSplit[0]);
int minorUserVersion = Integer.parseInt(userVersionSplit[1]);
int patchUserVersion = Integer.parseInt(userVersionSplit[2]);
int majorLatestVersion = Integer.parseInt(latestVersionSplit[0]);
int minorLatestVersion = Integer.parseInt(latestVersionSplit[1]);
int patchLatestVersion = Integer.parseInt(latestVersionSplit[2]);
if (majorUserVersion <= majorLatestVersion) {
if (majorUserVersion < majorLatestVersion) {
return true;
} else {
if (minorUserVersion <= minorLatestVersion) {
if (minorUserVersion < minorLatestVersion) {
return true;
} else {
return patchUserVersion < patchLatestVersion;
}
}
}
}
} catch (Exception ignored) {
// Will be throw only if the versions pattern is different from "x.x.x" format
// Will return false at the end
}
return false;
}
等待任何反馈:)
此代码尝试解决这种类型的比较版本。
大多数版本说明符,如>= 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;
}