Преобразовать строку версии semver (10.2.3) в long

1

Вот забавная задача...

Учитывая множество строк версии - если предположить, что они являются более или менее семантическими версиями семантических версий, например, 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) не будет работать должным образом, но я могу жить с этим. Но я хотел бы что-то быстрее.

  • 2
    Почему long ? Почему не класс с участниками для major, minor и patch (и других частей полуверсии)?
  • 0
    Хороший вопрос. В основном оптимизация, упрощение и совместимость. Длинные значения входят в другие (не Java) системы, и мы хотели что-то простое и супер быстрое для сравнения.
Показать ещё 1 комментарий
Теги:
string-parsing

1 ответ

0

Вы можете выполнить аналогичное преобразование в 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню