Проверка того, перечислены ли элементы в порядке убывания/возрастания

Использование Java + Selenium для автоматизации. Задача была проста:

  • Получить все продукты (WebElements) со страницы в список (1)
  • Форматирование данных (строка в десятичном виде) (2)
  • Проверить, находятся ли проанализированные данные в порядке возрастания/убывания (3)

Я реализовал решение, и оно работает, но, на мой взгляд, его можно сделать намного лучше и с меньшим количеством строк кода.

1:

List<WebElement> productPricesWE = baseMethods.findElements("ProductListing.ProductPrice");

Метод: "findElements" завернутый - думаю тут ничего не изменить)

2:

List<WebElement> productPricesWE = baseMethods.findElements("ProductListing.ProductPrice");
List<String> productPricesStringsAsc = new ArrayList<>();
for (WebElement webElement : productPricesWE) {
    productPricesStringsAsc.add(webElement.getText().trim());
}
List<BigDecimal> productPricesDecimalsAsc = new ArrayList<>();
for (String stringElement : productPricesStringsAsc) {
    productPricesDecimalsAsc.add(HelpersNL.cropAndParseToDecimal(stringElement));
}

public static BigDecimal cropAndParseToDecimal(final String productPriceAmount) throws ParseException {
    String decimalString = productPriceAmount.replaceAll("^..|.$", "");
    final NumberFormat format = NumberFormat.getNumberInstance(Locale.GERMAN);
    if (format instanceof DecimalFormat) {
        ((DecimalFormat) format).setParseBigDecimal(true);
    }
    return (BigDecimal) format.parse(decimalString);
}

Я просматриваю массивы, создаю один, перебираю, а затем добавляю данные в другой. На мой взгляд выглядит плохо и можно сделать проще

3:

Assert.assertTrue(Ordering.natural().isOrdered(productPricesDecimalsAsc));

Найдена правильная библиотека для ассертов, и она работает корректно.

Можете ли вы дать какие-либо советы и предложения, как код можно переписать или изменить, чтобы он выглядел лучше?

🤔 А знаете ли вы, что...
Java обеспечивает безопасность с помощью механизма байт-код верификации.


67
1

Ответ:

Решено

Есть несколько вещей, которые я могу порекомендовать.

  • Вы можете объединить свои два цикла, где вы .getText() получите строку, а затем преобразуете строку в число (с несколькими шагами) и просто выполните оба в этом одном цикле.

  • Ваша очистка строки и синтаксический анализ до числа могут быть упрощены. Вам не нужно удалять «$», а затем обрабатывать его. Вместо этого вы можете использовать NumberFormat.getCurrencyInstance() и напрямую использовать строку валюты. Это устраняет необходимость в cropAndParseToDecimal().

  • Вы используете Locale.GERMAN (язык), когда это должно быть Locale.GERMANY (страна). Сказав это, вы обрабатываете валюту США «$», поэтому вам действительно следует использовать Locale.US при разборе.

    Number n = NumberFormat.getCurrencyInstance(Locale.US).parse("$1.00")
    
  • Вам не нужны BigDecimals здесь, так как вы не пишете банковское приложение, вы просто собираете строки валюты с сайта и проверяете. Использование Double здесь должно работать быстрее.

Собрав все эти предложения,

List<WebElement> productPricesWE = baseMethods.findElements("ProductListing.ProductPrice");
List<Double> productPrices = new ArrayList<>();
for (WebElement element : productPricesWE) {
    String s = element.getText().trim().replaceAll("€* ", "");
    productPrices.add(NumberFormat.getNumberInstance(Locale.GERMANY).parse(s).doubleValue());
}

Assert.assertTrue(Ordering.natural().isOrdered(productPrices));

Сказав все это, я предполагаю, что мой код, вероятно, на 100 мс быстрее, чем ваш код, что незначительно в любом тесте веб-интерфейса. Мне он нравится немного больше не потому, что он быстрее, а потому, что некоторые функции проще и понятнее.

Помните правило, вы пишете код один раз и читаете его десять раз. Всегда предпочитайте читаемый код длинным «однострочникам» или чрезмерно укороченному коду.