Вот забавная задача...
Учитывая множество строк версии - если предположить, что они являются более или менее семантическими версиями семантических версий, например, 1.2.3 - какой способ конвертировать это в длинный (на Java), так что он считает, что "1.2.34" меньше, чем "12.3.0"?
Вот что я до сих пор
public static Long toLong(String version) {
if (version == null || version.isEmpty()) {
return 0L;
}
String[] parts = version.split("[^0-9]");
long number = 0L;
long factor = 1;
for (int b = parts.length - 1; b >= 0; b--) {
try {
Long l = Long.parseLong(parts[b]);
number += l * factor;
factor = factor * 100;
} catch (NumberFormatException e){
// silently ignored
}
}
return number;
}
Он предполагает, что никакая позиция в строке не может содержать более двух цифр (так что 1.2.3.4567) не будет работать должным образом, но я могу жить с этим. Но я хотел бы что-то быстрее.
Вы можете выполнить аналогичное преобразование в String
:
// add "." to format the major version
("." + versionString).
// replace each "." with "a00"
replaceAll("\\.", "a00").
// keep 2 digits, remove "a" and extra leading "0"
replaceAll("a0+([0-9]{2})", "$1");
Этот метод может быть легко принят для различного количества значащих цифр и/или разных форматов входной строки. Производительность ~ 2.4x медленнее, чем у вашего метода toLong (2,5 с для форматирования строк версии 1M). Если производительность важнее, чем простота кода, это примерно в 5,5 раз быстрее (0,2 с для строк 1 М), чем ваш метод toLong:
public static Long toLong2(String versionString)
{
if (versionString == null || versionString.isEmpty() )
{
return 0L;
} // end if empty
char[] C = versionString.toCharArray();
int i, i1 = 0, i2 = C.length;
Long l, number = 0L, factor = 1L;
try
{
for (i = C.length - 1; i > 0; i--)
{
if (C[i] == '.')
{
i1 = i + 1;
l = Long.parseLong(versionString.substring(i1, i2) );
i2 = i;
number += l * factor;
factor = factor * 100L;
} // end if '.'
} // end for i
l = Long.parseLong(versionString.substring(0, i2) );
number += l * factor;
}
catch (NumberFormatException e)
{
// silently ignored
} // end try
return number;
} // end method toLong2
long
? Почему не класс с участниками для major, minor и patch (и других частей полуверсии)?