是否有比较版本号的标准习语?我不能直接使用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
当前回答
也许有人会对我的解决方案感兴趣:
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
其他回答
下面是一个优化的实现:
public static final Comparator<CharSequence> VERSION_ORDER = new Comparator<CharSequence>() {
@Override
public int compare (CharSequence lhs, CharSequence rhs) {
int ll = lhs.length(), rl = rhs.length(), lv = 0, rv = 0, li = 0, ri = 0;
char c;
do {
lv = rv = 0;
while (--ll >= 0) {
c = lhs.charAt(li++);
if (c < '0' || c > '9')
break;
lv = lv*10 + c - '0';
}
while (--rl >= 0) {
c = rhs.charAt(ri++);
if (c < '0' || c > '9')
break;
rv = rv*10 + c - '0';
}
} while (lv == rv && (ll >= 0 || rl >= 0));
return lv - rv;
}
};
结果:
"0.1" - "1.0" = -1
"1.0" - "1.0" = 0
"1.0" - "1.0.0" = 0
"10" - "1.0" = 9
"3.7.6" - "3.7.11" = -5
"foobar" - "1.0" = -1
public int CompareVersions(String version1, String version2)
{
String[] string1Vals = version1.split("\\.");
String[] string2Vals = version2.split("\\.");
int length = Math.max(string1Vals.length, string2Vals.length);
for (int i = 0; i < length; i++)
{
Integer v1 = (i < string1Vals.length)?Integer.parseInt(string1Vals[i]):0;
Integer v2 = (i < string2Vals.length)?Integer.parseInt(string2Vals[i]):0;
//Making sure Version1 bigger than version2
if (v1 > v2)
{
return 1;
}
//Making sure Version1 smaller than version2
else if(v1 < v2)
{
return -1;
}
}
//Both are equal
return 0;
}
您需要规范化版本字符串,以便对它们进行比较。类似的
import java.util.regex.Pattern;
public class Main {
public static void main(String... args) {
compare("1.0", "1.1");
compare("1.0.1", "1.1");
compare("1.9", "1.10");
compare("1.a", "1.9");
}
private static void compare(String v1, String v2) {
String s1 = normalisedVersion(v1);
String s2 = normalisedVersion(v2);
int cmp = s1.compareTo(s2);
String cmpStr = cmp < 0 ? "<" : cmp > 0 ? ">" : "==";
System.out.printf("'%s' %s '%s'%n", v1, cmpStr, v2);
}
public static String normalisedVersion(String version) {
return normalisedVersion(version, ".", 4);
}
public static String normalisedVersion(String version, String sep, int maxWidth) {
String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
StringBuilder sb = new StringBuilder();
for (String s : split) {
sb.append(String.format("%" + maxWidth + 's', s));
}
return sb.toString();
}
}
打印
'1.0' < '1.1' '1.0.1' < '1.1' '1.9' < '1.10' “1。A ' > '1.9'
最好的方法是重用现有代码, 使用Maven的ComparableVersion类
优点:
Apache许可证,版本2.0, 测试, 在多个项目中使用(复制),如spring-security-core, jboss等 多个特性 它已经是java.lang。可比的了 只是复制粘贴一个类,没有第三方依赖
不要包含对maven-artifact的依赖项,因为那会拉动各种传递依赖项
我写了一个名为MgntUtils的开源库,它有一个用于字符串版本的实用程序。它正确地比较它们,适用于版本范围等等。下面是这个库javadoc参见方法TextUtils.comapreVersions(…)它已经被大量使用并经过了良好的测试。下面这篇文章描述了这个库以及如何获取它。它可以作为Maven工件和在github上获得(包括源代码和JavaDoc)