是否有比较版本号的标准习语?我不能直接使用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
当前回答
对于我的项目,我使用我的公共版本库https://github.com/raydac/commons-version 它包含两个辅助类-用于解析版本(解析后的版本可以与另一个版本对象进行比较,因为它是可比的)和VersionValidator,它允许检查一些表达式的版本,如!=ide-1.1.1,>idea-1.3.4-SNAPSHOT;<1.2.3
其他回答
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;
}
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);
}
}
使用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>
我现在就做了,然后问自己,这对吗?因为我从来没有找到过比我的更干净的解决方案
你只需要像下面这样拆分字符串版本("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;
}
等待任何反馈:)
科特林:
@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
}