是否有比较版本号的标准习语?我不能直接使用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
当前回答
我创建了一个简单的实用程序,使用语义版本约定在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 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;
}
下面是一个优化的实现:
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
使用Java 8 Stream替换组件中的前导零。这段代码通过了interviewbit.com上的所有测试
public int compareVersion(String A, String B) {
List<String> strList1 = Arrays.stream(A.split("\\."))
.map(s -> s.replaceAll("^0+(?!$)", ""))
.collect(Collectors.toList());
List<String> strList2 = Arrays.stream(B.split("\\."))
.map(s -> s.replaceAll("^0+(?!$)", ""))
.collect(Collectors.toList());
int len1 = strList1.size();
int len2 = strList2.size();
int i = 0;
while(i < len1 && i < len2){
if (strList1.get(i).length() > strList2.get(i).length()) return 1;
if (strList1.get(i).length() < strList2.get(i).length()) return -1;
int result = new Long(strList1.get(i)).compareTo(new Long(strList2.get(i)));
if (result != 0) return result;
i++;
}
while (i < len1){
if (!strList1.get(i++).equals("0")) return 1;
}
while (i < len2){
if (!strList2.get(i++).equals("0")) return -1;
}
return 0;
}
使用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
最好的方法是重用现有代码, 使用Maven的ComparableVersion类
优点:
Apache许可证,版本2.0, 测试, 在多个项目中使用(复制),如spring-security-core, jboss等 多个特性 它已经是java.lang。可比的了 只是复制粘贴一个类,没有第三方依赖
不要包含对maven-artifact的依赖项,因为那会拉动各种传递依赖项