你如何比较两个版本的字符串在Java?

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

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10
148579 次浏览

用点作为分隔符对字符串进行标记,然后从左边开始并排比较整数转换。

您需要规范化版本字符串,以便对它们进行比较。类似的

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

使用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>
// VersionComparator.java
import java.util.Comparator;


public class VersionComparator implements Comparator {


public boolean equals(Object o1, Object o2) {
return compare(o1, o2) == 0;
}


public int compare(Object o1, Object o2) {
String version1 = (String) o1;
String version2 = (String) o2;


VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
VersionTokenizer tokenizer2 = new VersionTokenizer(version2);


int number1 = 0, number2 = 0;
String suffix1 = "", suffix2 = "";


while (tokenizer1.MoveNext()) {
if (!tokenizer2.MoveNext()) {
do {
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
if (number1 != 0 || suffix1.length() != 0) {
// Version one is longer than number two, and non-zero
return 1;
}
}
while (tokenizer1.MoveNext());


// Version one is longer than version two, but zero
return 0;
}


number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();


if (number1 < number2) {
// Number one is less than number two
return -1;
}
if (number1 > number2) {
// Number one is greater than number two
return 1;
}


boolean empty1 = suffix1.length() == 0;
boolean empty2 = suffix2.length() == 0;


if (empty1 && empty2) continue; // No suffixes
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)


// Lexical comparison of suffixes
int result = suffix1.compareTo(suffix2);
if (result != 0) return result;


}
if (tokenizer2.MoveNext()) {
do {
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number2 != 0 || suffix2.length() != 0) {
// Version one is longer than version two, and non-zero
return -1;
}
}
while (tokenizer2.MoveNext());


// Version two is longer than version one, but zero
return 0;
}
return 0;
}
}


// VersionTokenizer.java
public class VersionTokenizer {
private final String _versionString;
private final int _length;


private int _position;
private int _number;
private String _suffix;
private boolean _hasValue;


public int getNumber() {
return _number;
}


public String getSuffix() {
return _suffix;
}


public boolean hasValue() {
return _hasValue;
}


public VersionTokenizer(String versionString) {
if (versionString == null)
throw new IllegalArgumentException("versionString is null");


_versionString = versionString;
_length = versionString.length();
}


public boolean MoveNext() {
_number = 0;
_suffix = "";
_hasValue = false;


// No more characters
if (_position >= _length)
return false;


_hasValue = true;


while (_position < _length) {
char c = _versionString.charAt(_position);
if (c < '0' || c > '9') break;
_number = _number * 10 + (c - '0');
_position++;
}


int suffixStart = _position;


while (_position < _length) {
char c = _versionString.charAt(_position);
if (c == '.') break;
_position++;
}


_suffix = _versionString.substring(suffixStart, _position);


if (_position < _length) _position++;


return true;
}
}

例子:

public class Main
{
private static VersionComparator cmp;


public static void main (String[] args)
{
cmp = new VersionComparator();
Test(new String[]{"1.1.2", "1.2", "1.2.0", "1.2.1", "1.12"});
Test(new String[]{"1.3", "1.3a", "1.3b", "1.3-SNAPSHOT"});
}


private static void Test(String[] versions) {
for (int i = 0; i < versions.length; i++) {
for (int j = i; j < versions.length; j++) {
Test(versions[i], versions[j]);
}
}
}


private static void Test(String v1, String v2) {
int result = cmp.compare(v1, v2);
String op = "==";
if (result < 0) op = "<";
if (result > 0) op = ">";
System.out.printf("%s %s %s\n", v1, op, v2);
}
}

输出:

1.1.2 == 1.1.2                --->  same length and value
1.1.2 < 1.2                   --->  first number (1) less than second number (2) => -1
1.1.2 < 1.2.0                 --->  first number (1) less than second number (2) => -1
1.1.2 < 1.2.1                 --->  first number (1) less than second number (2) => -1
1.1.2 < 1.12                  --->  first number (1) less than second number (12) => -1
1.2 == 1.2                    --->  same length and value
1.2 == 1.2.0                  --->  first shorter than second, but zero
1.2 < 1.2.1                   --->  first shorter than second, and non-zero
1.2 < 1.12                    --->  first number (2) less than second number (12) => -1
1.2.0 == 1.2.0                --->  same length and value
1.2.0 < 1.2.1                 --->  first number (0) less than second number (1) => -1
1.2.0 < 1.12                  --->  first number (2) less than second number (12) => -1
1.2.1 == 1.2.1                --->  same length and value
1.2.1 < 1.12                  --->  first number (2) less than second number (12) => -1
1.12 == 1.12                  --->  same length and value


1.3 == 1.3                    --->  same length and value
1.3 > 1.3a                    --->  first suffix ('') is empty, but not second ('a') => 1
1.3 > 1.3b                    --->  first suffix ('') is empty, but not second ('b') => 1
1.3 > 1.3-SNAPSHOT            --->  first suffix ('') is empty, but not second ('-SNAPSHOT') => 1
1.3a == 1.3a                  --->  same length and value
1.3a < 1.3b                   --->  first suffix ('a') compared to second suffix ('b') => -1
1.3a < 1.3-SNAPSHOT           --->  first suffix ('a') compared to second suffix ('-SNAPSHOT') => -1
1.3b == 1.3b                  --->  same length and value
1.3b < 1.3-SNAPSHOT           --->  first suffix ('b') compared to second suffix ('-SNAPSHOT') => -1
1.3-SNAPSHOT == 1.3-SNAPSHOT  --->  same length and value

这篇旧文章的另一个解决方案(对那些可能有帮助的人来说):

public class Version implements Comparable<Version> {


private String version;


public final String get() {
return this.version;
}


public Version(String version) {
if(version == null)
throw new IllegalArgumentException("Version can not be null");
if(!version.matches("[0-9]+(\\.[0-9]+)*"))
throw new IllegalArgumentException("Invalid version format");
this.version = version;
}


@Override public int compareTo(Version that) {
if(that == null)
return 1;
String[] thisParts = this.get().split("\\.");
String[] thatParts = that.get().split("\\.");
int length = Math.max(thisParts.length, thatParts.length);
for(int i = 0; i < length; i++) {
int thisPart = i < thisParts.length ?
Integer.parseInt(thisParts[i]) : 0;
int thatPart = i < thatParts.length ?
Integer.parseInt(thatParts[i]) : 0;
if(thisPart < thatPart)
return -1;
if(thisPart > thatPart)
return 1;
}
return 0;
}


@Override public boolean equals(Object that) {
if(this == that)
return true;
if(that == null)
return false;
if(this.getClass() != that.getClass())
return false;
return this.compareTo((Version) that) == 0;
}


}

Version a = new Version("1.1");
Version b = new Version("1.1.1");
a.compareTo(b) // return -1 (a<b)
a.equals(b)    // return false


Version a = new Version("2.0");
Version b = new Version("1.9.9");
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false


Version a = new Version("1.0");
Version b = new Version("1");
a.compareTo(b) // return 0 (a=b)
a.equals(b)    // return true


Version a = new Version("1");
Version b = null;
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false


List<Version> versions = new ArrayList<Version>();
versions.add(new Version("2"));
versions.add(new Version("1.0.5"));
versions.add(new Version("1.01.0"));
versions.add(new Version("1.00.1"));
Collections.min(versions).get() // return min version
Collections.max(versions).get() // return max version


// WARNING
Version a = new Version("2.06");
Version b = new Version("2.060");
a.equals(b)    // return false

编辑:

@daiscog:谢谢你的评论,这段代码是为Android平台开发的,由谷歌推荐,方法“匹配”检查整个字符串,不像Java使用监管模式。(__abc0 - __abc1)

我使用< >强语义版本控制< / >强约定在Android平台上创建了简单的实用程序用于比较版本。所以它只适用于X.Y.Z (Major.Minor.Patch)格式的字符串,其中X、Y和Z是非负整数。你可以在我的GitHub上找到它。

方法compareversions(字符串v1,字符串v2)比较两个版本字符串。如果版本相等则返回0,如果版本v1在版本v2之前则返回1,如果版本v1在版本v2之后则返回-1,如果版本格式无效则返回-2。

最好重用现有代码, 采取Maven的ComparableVersion类 < / p >

优点:

  • Apache许可证,版本2.0,
  • 测试,
  • 在多个项目中使用(复制),如spring-security-core, jboss等
  • 多个特性
  • 它已经是java.lang。可比的了
  • 只是复制粘贴一个类,没有第三方依赖

不要包含对maven-artifact的依赖项,因为那会拉动各种传递依赖项

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);
}
}
public static int compareVersions(String version1, String version2){


String[] levels1 = version1.split("\\.");
String[] levels2 = version2.split("\\.");


int length = Math.max(levels1.length, levels2.length);
for (int i = 0; i < length; i++){
Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0;
Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0;
int compare = v1.compareTo(v2);
if (compare != 0){
return compare;
}
}


return 0;
}

下面是一个优化的实现:

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

此代码尝试解决这种类型的比较版本。

大多数版本说明符,如>= 1.0,是不言自明的。的 说明符~>具有特殊含义,最好通过示例来说明。~> 2.0.3是 与>= 2.0.3和<2.1. ~> 2.1与>= 2.1和< 3.0 . < / p >
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;
}

对于我的项目,我使用我的common -version库https://github.com/raydac/commons-version 它包含两个辅助类——解析版本(解析后的版本可以与另一个版本对象进行比较,因为它是可比的)和VersionValidator,它允许检查一些表达式的版本,如!=ide-1.1.1,>idea-1.3.4-SNAPSHOT;<1.2.3

想知道为什么每个人都假设版本只由整数组成-在我的情况下,它不是。

为什么要重新发明轮子(假设版本遵循Semver标准)

首先通过Maven安装https://github.com/vdurmont/semver4j

然后使用这个库

Semver sem = new Semver("1.2.3");
sem.isGreaterThan("1.2.2"); // true

我喜欢@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;
}
/**
*  written by: Stan Towianski - May 2018
* notes: I make assumption each of 3 version sections a.b.c is not longer then 4 digits: aaaa.bbbb.cccc-MODWORD1(-)modnum2
* 5.10.13-release-1 becomes 0000500100013.501     6.0-snapshot becomes 0000600000000.100
* MODWORD1 = -xyz/NotMatching, -SNAPSHOT, -ALPHA, -BETA, -RC, -RELEASE/nothing  return:  .0, .1, .2, .3, .4, .5
* modnum2 = up to 2 digit/chars second version
* */
public class VersionCk {


private static boolean isVersionHigher( String baseVersion, String testVersion )
{
System.out.println( "versionToComparable( baseVersion ) =" + versionToComparable( baseVersion ) );
System.out.println( "versionToComparable( testVersion ) =" + versionToComparable( testVersion ) + " is this higher ?" );
return versionToComparable( testVersion ).compareTo( versionToComparable( baseVersion ) ) > 0;
}


//----  not worrying about += for something so small
private static String versionToComparable( String version )
{
//        System.out.println("version - " + version);
String versionNum = version;
int at = version.indexOf( '-' );
if ( at >= 0 )
versionNum = version.substring( 0, at );


String[] numAr = versionNum.split( "\\." );
String versionFormatted = "0";
for ( String tmp : numAr )
{
versionFormatted += String.format( "%4s", tmp ).replace(' ', '0');
}
while ( versionFormatted.length() < 12 )  // pad out to aaaa.bbbb.cccc
{
versionFormatted += "0000";
}
//        System.out.println( "converted min version =" + versionFormatted + "=   : " + versionNum );
return versionFormatted + getVersionModifier( version, at );
}


//----  use order low to high: -xyz, -SNAPSHOT, -ALPHA, -BETA, -RC, -RELEASE/nothing  returns: 0, 1, 2, 3, 4, 5
private static String getVersionModifier( String version, int at )
{
//        System.out.println("version - " + version );
String[] wordModsAr = { "-SNAPSHOT", "-ALPHA", "-BETA", "-RC", "-RELEASE" };


if ( at < 0 )
return "." + wordModsAr.length + "00";   // make nothing = RELEASE level


int i = 1;
for ( String word : wordModsAr )
{
if ( ( at = version.toUpperCase().indexOf( word ) ) > 0 )
return "." + i + getSecondVersionModifier( version.substring( at + word.length() ) );
i++;
}


return ".000";
}


//----  add 2 chars for any number after first modifier.  -rc2 or -rc-2   returns 02
private static String getSecondVersionModifier( String version )
{
System.out.println( "second modifier =" + version + "=" );
Matcher m = Pattern.compile("(.*?)(\\d+).*").matcher( version );
//        if ( m.matches() )
//            System.out.println( "match ? =" + m.matches() + "=   m.group(1) =" + m.group(1) + "=   m.group(2) =" + m.group(2) + "=   m.group(3) =" + (m.groupCount() >= 3 ? m.group(3) : "x") );
//        else
//            System.out.println( "No match" );
return m.matches() ? String.format( "%2s", m.group(2) ).replace(' ', '0') : "00";
}


public static void main(String[] args)
{
checkVersion( "3.10.0", "3.4.0");
checkVersion( "5.4.2", "5.4.1");
checkVersion( "5.4.4", "5.4.5");
checkVersion( "5.4.9", "5.4.12");
checkVersion( "5.9.222", "5.10.12");
checkVersion( "5.10.12", "5.10.12");
checkVersion( "5.10.13", "5.10.14");
checkVersion( "6.7.0", "6.8");
checkVersion( "6.7", "2.7.0");
checkVersion( "6", "6.3.1");
checkVersion( "4", "4.0.0");
checkVersion( "6.3.0", "6");
checkVersion( "5.10.12-Alpha", "5.10.12-beTA");
checkVersion( "5.10.13-release", "5.10.14-beta");
checkVersion( "6.7.0", "6.8-snapshot");
checkVersion( "6.7.1", "6.7.0-release");
checkVersion( "6-snapshot", "6.0.0-beta");
checkVersion( "6.0-snapshot", "6.0.0-whatthe");
checkVersion( "5.10.12-Alpha-1", "5.10.12-alpha-2");
checkVersion( "5.10.13-release-1", "5.10.13-release2");
checkVersion( "10-rc42", "10.0.0-rc53");
}


private static void checkVersion(String baseVersion, String testVersion)
{
System.out.println( "baseVersion - " + baseVersion );
System.out.println( "testVersion - " + testVersion );
System.out.println( "isVersionHigher = " + isVersionHigher( baseVersion, testVersion ) );
System.out.println( "---------------");
}


}

一些输出:

---------------
baseVersion - 6.7
testVersion - 2.7.0
versionToComparable( baseVersion ) =0000600070000.500
versionToComparable( testVersion ) =0000200070000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 6
testVersion - 6.3.1
versionToComparable( baseVersion ) =0000600000000.500
versionToComparable( testVersion ) =0000600030001.500 is this higher ?
isVersionHigher = true
---------------
baseVersion - 4
testVersion - 4.0.0
versionToComparable( baseVersion ) =0000400000000.500
versionToComparable( testVersion ) =0000400000000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 6.3.0
testVersion - 6
versionToComparable( baseVersion ) =0000600030000.500
versionToComparable( testVersion ) =0000600000000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 5.10.12-Alpha
testVersion - 5.10.12-beTA
second modifier ==
versionToComparable( baseVersion ) =0000500100012.200
second modifier ==
versionToComparable( testVersion ) =0000500100012.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 5.10.13-release
testVersion - 5.10.14-beta
second modifier ==
versionToComparable( baseVersion ) =0000500100013.500
second modifier ==
versionToComparable( testVersion ) =0000500100014.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.7.0
testVersion - 6.8-snapshot
versionToComparable( baseVersion ) =0000600070000.500
second modifier ==
versionToComparable( testVersion ) =0000600080000.100 is this higher ?
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.7.1
testVersion - 6.7.0-release
versionToComparable( baseVersion ) =0000600070001.500
second modifier ==
versionToComparable( testVersion ) =0000600070000.500 is this higher ?
second modifier ==
isVersionHigher = false
---------------
baseVersion - 6-snapshot
testVersion - 6.0.0-beta
second modifier ==
versionToComparable( baseVersion ) =0000600000000.100
second modifier ==
versionToComparable( testVersion ) =0000600000000.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.0-snapshot
testVersion - 6.0.0-whatthe
second modifier ==
versionToComparable( baseVersion ) =0000600000000.100
versionToComparable( testVersion ) =0000600000000.000 is this higher ?
second modifier ==
isVersionHigher = false
---------------
baseVersion - 5.10.12-Alpha-1
testVersion - 5.10.12-alpha-2
second modifier =-1=
versionToComparable( baseVersion ) =0000500100012.201
second modifier =-2=
versionToComparable( testVersion ) =0000500100012.202 is this higher ?
second modifier =-2=
second modifier =-1=
isVersionHigher = true
---------------
baseVersion - 5.10.13-release-1
testVersion - 5.10.13-release2
second modifier =-1=
versionToComparable( baseVersion ) =0000500100013.501
second modifier =2=
versionToComparable( testVersion ) =0000500100013.502 is this higher ?
second modifier =2=
second modifier =-1=
isVersionHigher = true
---------------
baseVersion - 10-rc42
testVersion - 10.0.0-rc53
second modifier =42=
versionToComparable( baseVersion ) =0001000000000.442
second modifier =53=
versionToComparable( testVersion ) =0001000000000.453 is this higher ?
second modifier =53=
second modifier =42=
isVersionHigher = true
---------------

如果你的项目中已经有Jackson,你可以使用com.fasterxml.jackson.core.Version:

import com.fasterxml.jackson.core.Version;
import org.junit.Test;


import static org.junit.Assert.assertTrue;


public class VersionTest {


@Test
public void shouldCompareVersion() {
Version version1 = new Version(1, 11, 1, null, null, null);
Version version2 = new Version(1, 12, 1, null, null, null);
assertTrue(version1.compareTo(version2) < 0);
}
}

我写了一个名为MgntUtils的开源库,它有一个用于字符串版本的实用程序。它正确地比较它们,适用于版本范围等等。下面是这个库javadoc参见方法TextUtils.comapreVersions(...)。它已经被大量使用并经过了良好的测试。下面是文章,它描述了这个库以及从哪里获取它。它可以通过Maven工件github(包含源代码和JavaDoc)获得。

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

我写了一个小的Java/Android库来比较版本号:https://github.com/G00fY2/version-compare

它的基本功能是:

  public int compareVersions(String versionA, String versionB) {
String[] versionTokensA = versionA.split("\\.");
String[] versionTokensB = versionB.split("\\.");
List<Integer> versionNumbersA = new ArrayList<>();
List<Integer> versionNumbersB = new ArrayList<>();


for (String versionToken : versionTokensA) {
versionNumbersA.add(Integer.parseInt(versionToken));
}
for (String versionToken : versionTokensB) {
versionNumbersB.add(Integer.parseInt(versionToken));
}


final int versionASize = versionNumbersA.size();
final int versionBSize = versionNumbersB.size();
int maxSize = Math.max(versionASize, versionBSize);


for (int i = 0; i < maxSize; i++) {
if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return 1;
} else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return -1;
}
}
return 0;
}

这个代码片段不提供任何错误检查或处理。除此之外,我的库还支持像“1.2-rc”>“1.2-beta”这样的后缀。

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

由于本页上没有答案能很好地处理混合文本,我做了自己的版本:

import java.util.regex.Matcher;
import java.util.regex.Pattern;


class Main {
static double parseVersion(String v) {
if (v.isEmpty()) {
return 0;
}
Pattern p = Pattern.compile("^(\\D*)(\\d*)(\\D*)$");
Matcher m = p.matcher(v);
m.find();
if (m.group(2).isEmpty()) {
// v1.0.0.[preview]
return -1;
}
double i = Integer.parseInt(m.group(2));
if (!m.group(3).isEmpty()) {
// v1.0.[0b]
i -= 0.1;
}
return i;
}


public static int versionCompare(String str1, String str2) {
String[] v1 = str1.split("\\.");
String[] v2 = str2.split("\\.");
int i = 0;
for (; i < v1.length && i < v2.length; i++) {
double iv1 = parseVersion(v1[i]);
double iv2 = parseVersion(v2[i]);


if (iv1 != iv2) {
return iv1 - iv2 < 0 ? -1 : 1;
}
}
if (i < v1.length) {
// "1.0.1", "1.0"
double iv1 = parseVersion(v1[i]);
return iv1 < 0 ? -1 : (int) Math.ceil(iv1);
}
if (i < v2.length) {
double iv2 = parseVersion(v2[i]);
return -iv2 < 0 ? -1 : (int) Math.ceil(iv2);
}
return 0;
}




public static void main(String[] args) {
System.out.println("versionCompare(v1.0.0, 1.0.0)");
System.out.println(versionCompare("v1.0.0", "1.0.0")); // 0


System.out.println("versionCompare(v1.0.0b, 1.0.0)");
System.out.println(versionCompare("v1.0.0b", "1.0.0")); // -1


System.out.println("versionCompare(v1.0.0.preview, 1.0.0)");
System.out.println(versionCompare("v1.0.0.preview", "1.0.0")); // -1


System.out.println("versionCompare(v1.0, 1.0.0)");
System.out.println(versionCompare("v1.0", "1.0.0")); // 0


System.out.println("versionCompare(ver1.0, 1.0.1)");
System.out.println(versionCompare("ver1.0", "1.0.1")); // -1
}
}

在需要比较“alpha"与“beta"虽然。

对于要显示基于版本号的强制更新警报的人,我有以下想法。这可能用于比较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 < / p >
public static void main(String[] args) {


String version1 = "1.0";
String version2 = "1.0.0";
String[] version1_splits = version1.split("\\.");
String[] version2_splits = version2.split("\\.");
int length = version1_splits.length >= version2_splits.length ? version1_splits.length : version2_splits.length;
int i=0;
for(;i<length;i++){
int version1_int = getValue(version1_splits,i);
int version2_int = getValue(version2_splits,i);
if(version1_int > version2_int){
System.out.println("version1 > version2");
break;
}
else if(version1_int < version2_int){
System.out.println("version2 > version1");
break;
}
else{
if(i == length-1)
System.out.println("version1 = version2");
}
}
}


private static int getValue(String[] version1_splits, int i) {
int temp;
try{
temp = Integer.valueOf(version1_splits[i]);
}
catch(IndexOutOfBoundsException e){
temp=0;
}


return temp;
}

我现在就做了,然后问自己,这对吗?因为我从来没有找到过比我的更干净的解决方案

你只需要像下面这个例子一样拆分字符串版本("1.0.0")

userVersion.split("\\.")

那么你将会有:{"1", "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;
}

等待任何反馈:)

@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

基于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"))

也许有人会对我的解决方案感兴趣:

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


使用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);
}
}

< a href = " https://tio.run/ # # dZI9b8JADIb3 / AqLKVTlyNEN1AGp3cqE1KXq4CQXcnC5i@xLEKr47WkaUAkBJsuvH3 / I9hZrnGzTXdPoonTkYdsKovLaiKdF0NcM2o0oXFoZJVadeVOckC69I / GpiLWziyAxyAwr1BZ@AoCyio1OgD361tROp1C0sXDtSdvN1zcgbXjcoQA1EtSnQgyvsCTCAwvkD80@7AiAkRSRmI2e@240iZXHG / UeNNTQlDkKeb@glNfy0JXDLEqEfNChL8vb2U7UcEL5kJQzgfEkuQSj4XyzB6MMxD8KYDqFpWEHe0c7hr32OSDYqogVgcuAVeK7o6Q6yxQp68HnaOHlulRvi / 2 frjcto1enjbens59pltitwiicn2lrybmeh2s@l5fy / Ye4fUuVXtDM0Tsmebg@sFeFcJVvM9oX88Z2XY7BsWl@AQ”rel = title =“noreferrer Java (JDK)——试一试在网上试试吧!< / >

输出:

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

芬兰湾的科特林:

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