Автор оригинала: Sam Millington.
1. введение
В этом уроке мы рассмотрим, как сортировать буквенно-цифровые String s по содержащимся в них числам. Мы сосредоточимся на удалении всех нечисловых символов из Строки перед сортировкой нескольких Строк по оставшимся числовым символам.
Мы рассмотрим общие случаи ребер, включая пустые Строки s и недопустимые числа.
Наконец, мы проведем модульное тестирование нашего решения, чтобы убедиться, что оно работает должным образом.
2. Изложение проблемы
Прежде чем мы начнем, нам нужно описать, чего мы хотим достичь в нашем коде. Для этой конкретной проблемы мы сделаем следующие предположения:
- Наши строки могут содержать только цифры, только буквы или их сочетание.
- Числа в наших строках могут быть целыми или двойными.
- Когда числа в строке разделены буквами, мы должны удалить букву и сжать цифры вместе. Например, 2d3 становится 23.
- Для простоты, когда появляется недопустимое или отсутствующее число, мы должны рассматривать их как 0.
Установив это, давайте застрянем в нашем решении.
3. Решение Регулярных Выражений
Поскольку наш первый шаг-поиск числовых шаблонов в нашей входной строке , мы можем использовать регулярные выражения, обычно известные как регулярное выражение.
Первое, что нам нужно, – это наше регулярное выражение. Мы хотим сохранить все целые числа, а также десятичные точки из входных данных String . Мы можем достичь нашей цели с помощью следующего:
String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]" String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");
Давайте вкратце объясним, что происходит:
- ‘[^ ]’ – обозначает отрицаемый набор, поэтому нацеливается на любой символ, не указанный в прилагаемом регулярном выражении
- ‘\d’ – соответствует любому значному символу (0 – 9)
- ‘.’ – соответствует любому символу “.”
Затем мы используем метод String.replaceAll для удаления любых символов, не указанных в нашем регулярном выражении. Делая это, мы можем гарантировать, что первые три пункта нашей цели будут достигнуты.
Далее нам нужно добавить некоторые условия, чтобы гарантировать, что пустые и недопустимые Строки возвращают 0, в то время как допустимые Строки возвращают допустимый Двойной :
if("".equals(digitsOnly)) return 0; try { return Double.parseDouble(digitsOnly); } catch (NumberFormatException nfe) { return 0; }
Это завершает нашу логику. Все, что осталось сделать, это подключить его к компаратору, чтобы мы могли удобно сортировать Списки входных Строк.
Давайте создадим эффективный метод для возврата нашего компаратора из любого места, где он нам может понадобиться:
public static ComparatorcreateNaturalOrderRegexComparator() { return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber); }
4. Тест, Тест, Тест
Что хорошего в коде без тестов для проверки его функциональности? Давайте проведем быстрый модульный тест, чтобы убедиться, что все работает так, как мы планировали:
ListtestStrings = Arrays.asList("a1", "d2.2", "b3", "d2.3.3d", "c4", "d2.f4",); // 1, 2.2, 3, 0, 4, 2.4 testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); List expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4"); assertEquals(expected, testStrings);
В этом модульном тесте мы собрали все сценарии, которые мы запланировали. Недопустимые числа, целые числа, десятичные дроби и числа, разделенные буквами, все они включены в нашу переменную test Strings .
5. Заключение
В этой короткой статье мы продемонстрировали, как сортировать буквенно – цифровые строки на основе чисел в них, используя регулярные выражения для выполнения тяжелой работы за нас.
Мы обработали стандартные исключения, которые могут возникнуть при разборе входных строк, и протестировали различные сценарии с помощью модульного тестирования.
Как всегда, код можно найти на GitHub.