// 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) {
// La version un est plus longue que la version deux, et non nulle
return 1;
}
}
while (tokenizer1.MoveNext());
// La version un est plus longue que la version deux, mais nulle
return 0;
}
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number1 < number2) {
// Le nombre un est inférieur au nombre deux
return -1;
}
if (number1 > number2) {
// Le nombre un est supérieur au nombre deux
return 1;
}
boolean empty1 = suffix1.length() == 0;
boolean empty2 = suffix2.length() == 0;
if (empty1 && empty2) continue; // Pas de suffixes
if (empty1) return 1; // Premier suffixe est vide (1.2 > 1.2b)
if (empty2) return -1; // Deuxième suffixe est vide (1.2a < 1.2)
// Comparaison lexicographique des 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) {
// La version un est plus longue que la version deux, et non nulle
return -1;
}
}
while (tokenizer2.MoveNext());
// La version deux est plus longue que la version un, mais nulle
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;
// Plus de caractères
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;
}
}
Exemple:
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);
}
}
Sortie:
1.1.2 == 1.1.2 ---> même longueur et même valeur
1.1.2 < 1.2 ---> premier nombre (1) inférieur au deuxième nombre (2) => -1
1.1.2 < 1.2.0 ---> premier nombre (1) inférieur au deuxième nombre (2) => -1
1.1.2 < 1.2.1 ---> premier nombre (1) inférieur au deuxième nombre (2) => -1
1.1.2 < 1.12 ---> premier nombre (1) inférieur au deuxième nombre (12) => -1
1.2 == 1.2 ---> même longueur et même valeur
1.2 == 1.2.0 ---> premier plus court que deuxième, mais zéro
1.2 < 1.2.1 ---> premier plus court que deuxième, et non nul
1.2 < 1.12 ---> premier nombre (2) inférieur au deuxième nombre (12) => -1
1.2.0 == 1.2.0 ---> même longueur et même valeur
1.2.0 < 1.2.1 ---> premier nombre (0) inférieur au deuxième nombre (1) => -1
1.2.0 < 1.12 ---> premier nombre (2) inférieur au deuxième nombre (12) => -1
1.2.1 == 1.2.1 ---> même longueur et même valeur
1.2.1 < 1.12 ---> premier nombre (2) inférieur au deuxième nombre (12) => -1
1.12 == 1.12 ---> même longueur et même valeur
1.3 == 1.3 ---> même longueur et même valeur
1.3 > 1.3a ---> premier suffixe ('') est vide, mais pas le deuxième ('a') => 1
1.3 > 1.3b ---> premier suffixe ('') est vide, mais pas le deuxième ('b') => 1
1.3 > 1.3-SNAPSHOT ---> premier suffixe ('') est vide, mais pas le deuxième ('-SNAPSHOT') => 1
1.3a == 1.3a ---> même longueur et même valeur
1.3a < 1.3b ---> premier suffixe ('a') comparé au deuxième suffixe ('b') => -1
1.3a < 1.3-SNAPSHOT ---> premier suffixe ('a') comparé au deuxième suffixe ('-SNAPSHOT') => -1
1.3b == 1.3b ---> même longueur et même valeur
1.3b < 1.3-SNAPSHOT ---> premier suffixe ('b') comparé au deuxième suffixe ('-SNAPSHOT') => -1
1.3-SNAPSHOT == 1.3-SNAPSHOT ---> même longueur et même valeur
0 votes
Avez-vous essayé simplement de supprimer les points et de parser la chaîne résultante en tant que entier ? Actuellement, j'utilise quelque chose de similaire à ce qui suit :
String version = "1.1.2".replace(".", "");
int number = Integer.parseInt(version); // = 112
. Vous pourriez comparer le numéro à un autre et ainsi trouver la version la plus récente. De plus, vous pouvez vérifier si la chaîneversion
correspond à un certain motif comme\\d+\\.\\d+\\.\\d
pour vous assurer que le résultat comporte au moins 3 chiffres.8 votes
@RegisteredUser Comment cela fonctionnerait-il avec quelque chose comme ceci : 1.12.1 et 1.1.34 ?
0 votes
Vous devriez vous assurer que chaque partie a la même longueur. Ainsi, pour comparer les deux versions de votre exemple, elles doivent ressembler à ceci: 1.12.01 et 1.01.34. En Java, vous pourriez y parvenir en fractionnant d'abord à l'aide de la balise
.
et en comparant ensuite la longueur de chaque élément. Ensuite, il suffit de mettre tous les éléments dans une seule chaîne, de la convertir en entier, puis de la comparer à l'autre version qui a été convertie de la même manière.0 votes
Je voulais juste partager que cela pourrait être étonnamment court mis en œuvre en groovy stackoverflow.com/a/7737400/1195507