Last active
August 29, 2015 14:06
-
-
Save ctmay4/ed29228f571712c7e210 to your computer and use it in GitHub Desktop.
Version string sorting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Comparator; | |
/** | |
* A Comparator for version strings. Version strings are assumed to be only numbers and periods. Here are | |
* some examples: | |
* <p/> | |
* 1.0 | |
* 3.4.1 | |
* 123.43.123.1 | |
* <p/> | |
* In the comparison, the versions are evaluated from left to right, one integer at a time. For example, | |
* here is a list of version strings in order from lowest to highest | |
* <p/> | |
* 3.9.9.1 | |
* 4.1 | |
* 4.2 | |
* 4.2.1 | |
* 4.2.3 | |
* 4.3 | |
* <p/> | |
* The class is designed to work with version that contain only integer parts. It will not throw an | |
* exception of the version string contains non-numerics, but the ordering is undefined for those versions. | |
*/ | |
public class VersionComparator implements Comparator<String> { | |
/** | |
* Compare two versions | |
* @param version1 | |
* @param version2 | |
* @return | |
*/ | |
@Override | |
public int compare(String version1, String version2) { | |
// Split version into parts | |
String[] parts1 = getVersionParts(version1); | |
String[] parts2 = getVersionParts(version2); | |
// Go through common prefix left to right, first part which is higher indicates higher | |
// version (4.2.1 > 4.2.0 > 3.9.9) | |
for (int i = 0; i < Math.min(parts1.length, parts2.length); i++) { | |
int partComparison = compareVersionPart(parts1[i], parts2[i]); | |
if (partComparison != 0) { | |
return partComparison; | |
} | |
} | |
// Common prefix is the same; longer value means higher version (3.2.1 > 3.2) | |
if (parts1.length > parts2.length) | |
return 1; | |
else if (parts1.length < parts2.length) | |
return -1; | |
else | |
return 0; | |
} | |
/** | |
* Split a version string into indiviual parts between the periods | |
* @param version | |
* @return | |
*/ | |
protected String[] getVersionParts(String version) { | |
return version.split("\\."); | |
} | |
/** | |
* Compare two date parts as integers | |
* @param part1 | |
* @param part2 | |
* @return | |
*/ | |
protected int compareVersionPart(String part1, String part2) { | |
int versionPart1 = convertPartToInteger(part1); | |
int versionPart2 = convertPartToInteger(part2); | |
if (versionPart1 > versionPart2) | |
return 1; | |
else if (versionPart1 < versionPart2) | |
return -1; | |
else | |
return 0; | |
} | |
/** | |
* Convert the string to an Integer. If it cannot be converted, return zero. | |
* @param part | |
* @return | |
*/ | |
private int convertPartToInteger(String part) { | |
try { | |
return Integer.parseInt(part); | |
} | |
catch (NumberFormatException e) { | |
return 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment