Класс ArrayUtils
Класс ArrayUtils реализует пакет служебных методов, которые позволяют нам обрабатывать и проверять массивы во многих различных формах и формах .
Давайте начнем с двух перегруженных реализаций метода toString () , который возвращает строку представление данного массива и конкретную строку , когда массив равен нулю:
@Test public void whenCalledtoString_thenCorrect() { String[] array = {"a", "b", "c"}; assertThat(ArrayUtils.toString(array)) .isEqualTo("{a,b,c}"); } @Test public void whenCalledtoStringIfArrayisNull_thenCorrect() { assertThat(ArrayUtils.toString(null, "Array is null")) .isEqualTo("Array is null"); }
Далее у нас есть методы hashcode() и to Map () .
Первый генерирует пользовательскую реализацию hashCode для массива, в то время как последний преобразует массив в карту :
@Test public void whenCalledhashCode_thenCorrect() { String[] array = {"a", "b", "c"}; assertThat(ArrayUtils.hashCode(array)) .isEqualTo(997619); } @Test public void whenCalledtoMap_thenCorrect() { String[][] array = {{"1", "one", }, {"2", "two", }, {"3", "three"}}; Map map = new HashMap(); map.put("1", "one"); map.put("2", "two"); map.put("3", "three"); assertThat(ArrayUtils.toMap(array)) .isEqualTo(map); }
Наконец, давайте рассмотрим методы is Same Length() и indexOf () .
Первый используется для проверки, имеют ли два массива одинаковую длину, а второй-для получения индекса данного элемента:
@Test public void whenCalledisSameLength_thenCorrect() { int[] array1 = {1, 2, 3}; int[] array2 = {1, 2, 3}; assertThat(ArrayUtils.isSameLength(array1, array2)) .isTrue(); } @Test public void whenCalledIndexOf_thenCorrect() { int[] array = {1, 2, 3}; assertThat(ArrayUtils.indexOf(array, 1, 0)) .isEqualTo(0); }
Как и в случае с классом StringUtils , ArrayUtils реализует гораздо больше дополнительных методов. Вы можете узнать больше о них в этом уроке .
В данном случае мы продемонстрировали только самые репрезентативные из них.
Округление Удваивается С Помощью BigDecimal
Чтобы округлить double s до n десятичных знаков, мы можем написать вспомогательный метод :
private static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = new BigDecimal(Double.toString(value)); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); }
В этом решении следует отметить одну важную вещь: при построении BigDecimal мы должны всегда использовать BigDecimal(String) конструктор . Это предотвращает проблемы с представлением неточных значений.
Мы можем достичь того же результата, используя библиотеку Apache Commons Math :
org.apache.commonscommons-math33.5
Последнюю версию можно найти .
Как только мы добавим библиотеку в проект, мы сможем использовать Precision.round() метод, который принимает два аргумента – value и scale:
Precision.round(PI, 3);
По умолчанию он использует тот же метод округления HALF_UP , что и наш вспомогательный метод; поэтому результаты должны быть одинаковыми.
Обратите внимание, что мы можем изменить поведение округления, передав нужный метод округления в качестве третьего параметра
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Этот код должен возвращать:
String is numeric!
NumberUtils.isCreatable()
Этот метод также принимает строку и проверяет, является ли она допустимым номером Java . С помощью этого метода мы можем охватить еще больше чисел, потому что допустимое число Java включает в себя четные шестнадцатеричные и восьмеричные числа, научную нотацию, а также числа, отмеченные классификатором типа.
Теперь мы можем даже использовать что-то вроде:
String string = "0x10AB"; if (NumberUtils.isCreatable(string)) { System.out.println("String contains a creatable number!"); } else { System.out.println("String doesn't contain creatable number."); }
Результатом будет:
String contains a creatable number!
числа.isDigits()
Число проверяет, содержит ли строка только Цифры в Юникоде. Если содержит начальный знак или десятичную точку, метод вернет :
String string = "25"; if (NumberUtils.isDigits(string)) { System.out.println("String is numeric!"); } else { System.out.println("String isn't numeric."); }
StringUtils.IsNumeric()
является эквивалентом .
Если проходит числовой тест, она все равно может вызвать исключение при анализе методами, о которых мы упоминали ранее, например, если она находится вне диапазона для или .
Используя этот метод, мы можем определить, можем ли мы проанализировать в :
String string = "25"; if (StringUtils.isNumeric(string)) { System.out.println("String is numeric!"); } else { System.out.println("String isn't numeric."); }
StringUtils.isNumericSpace()
Кроме того, если мы ожидаем найти больше чисел в строке, мы можем использовать , еще один полезный метод, о котором стоит упомянуть. Он проверяет, содержит ли строка пробелы .
Давайте проверим строку, содержащую числа и пробелы:
String string = "25 50 15"; if (StringUtils.isNumericSpace(string)) { System.out.println("String is numeric!"); } else { System.out.println("String isn't numeric."); }
Это приводит к:
String is numeric!
Проверьте, является ли строка числовой с помощью регулярного выражения
Несмотря на то, что большинство разработчиков будут довольны использованием уже реализованного метода, иногда у вас может быть очень специфическая проверка шаблонов:
public static boolean isNumeric(String string) { // Checks if the provided string // is a numeric by applying a regular // expression on it. String regex = "+?*"; return Pattern.matches(regex, string); }
И тогда мы можем вызвать этот метод:
System.out.println("123: " + isStringNumeric2("123")); System.out.println("I'm totally a numeric, trust me: " + isStringNumeric2("I'm totally a numeric, trust me"));
Выполнение этого дает нам следующий результат:
123: true I'm totally a numeric, trust me: false
Вывод
В этой статье мы рассмотрели несколько способов проверить, является ли строка числовой или нет (представляет собой число) в Java.
Мы начали использовать ядро Java и поймали исключение , после чего мы использовали библиотеку Apache Commons. Оттуда мы использовали классы и , чтобы проверить, является ли строка числовой или нет, в различных форматах.
Использование ядра Java
Давайте теперь посмотрим, как мы можем выполнить ту же проверку, если мы не хотим использовать регулярные выражения. Мы воспользуемся классами Character и String и их методами, чтобы проверить, присутствуют ли все необходимые символы в нашей String :
private static boolean checkString(String input) { String specialChars = "~`#$%^&*()-_=+\\|};:'\",<.>/?"; char currentCharacter; boolean numberPresent = false; boolean upperCasePresent = false; boolean lowerCasePresent = false; boolean specialCharacterPresent = false; for (int i = 0; i < input.length(); i++) { currentCharacter = input.charAt(i); if (Character.isDigit(currentCharacter)) { numberPresent = true; } else if (Character.isUpperCase(currentCharacter)) { upperCasePresent = true; } else if (Character.isLowerCase(currentCharacter)) { lowerCasePresent = true; } else if (specialChars.contains(String.valueOf(currentCharacter))) { specialCharacterPresent = true; } } return numberPresent && upperCasePresent && lowerCasePresent && specialCharacterPresent; }
Здесь мы должны отметить несколько вещей. Основная идея заключается в том, что мы перебираем нашу Строку и проверяем, соответствуют ли ее символы требуемым типам. Используя класс Character , мы можем легко проверить, является ли определенный символ цифрой, прописным или строчным символом.
К сожалению, нет подобного метода, который бы подсказал нам, имеем ли мы дело с одним из специальных символов. Таким образом, это означает, что нам нужно использовать другой подход.
Мы создали строку |, содержащую все необходимые специальные символы, а затем проверили, содержит ли она наш конкретный символ.
Класс NumberUtils
Еще одним ключевым компонентом Apache Commons Lang 3 является класс NumberUtils .
Как и ожидалось, класс предоставляет большое количество полезных методов, направленных на обработку и манипулирование числовыми типами .
Давайте рассмотрим перегруженные реализации метода compare () , который сравнивает равенство различных примитивов, таких как int и long :
@Test public void whenCalledcompareWithIntegers_thenCorrect() { assertThat(NumberUtils.compare(1, 1)) .isEqualTo(0); } @Test public void whenCalledcompareWithLongs_thenCorrect() { assertThat(NumberUtils.compare(1L, 1L)) .isEqualTo(0); }
Кроме того, существуют реализации compare () , которые работают с byte и short , которые работают очень похоже на приведенные выше примеры.
Далее в этом обзоре приведены методы create Number() и isDigit () .
Первый позволяет нам создать числовое представление string , в то время как второй проверяет, состоит ли string только из цифр:
@Test public void whenCalledcreateNumber_thenCorrect() { assertThat(NumberUtils.createNumber("123456")) .isEqualTo(123456); } @Test public void whenCalledisDigits_thenCorrect() { assertThat(NumberUtils.isDigits("123456")).isTrue(); }
Когда дело доходит до поиска смешанных и максимальных значений поставляемого массива, класс NumberUtils обеспечивает сильную поддержку этих операций с помощью перегруженных реализаций методов min() и max() :
@Test public void whenCalledmaxwithIntegerArray_thenCorrect() { int[] array = {1, 2, 3, 4, 5, 6}; assertThat(NumberUtils.max(array)) .isEqualTo(6); } @Test public void whenCalledminwithIntegerArray_thenCorrect() { int[] array = {1, 2, 3, 4, 5, 6}; assertThat(NumberUtils.min(array)).isEqualTo(1); } @Test public void whenCalledminwithByteArray_thenCorrect() { byte[] array = {1, 2, 3, 4, 5, 6}; assertThat(NumberUtils.min(array)) .isEqualTo((byte) 1); }
Проверка с помощью DateTimeFormatter
В предыдущем разделе мы видели, что LocalDate использует DateTimeFormatter объект для синтаксического анализа. Мы также можем использовать класс DateTimeFormatter непосредственно для форматирования и синтаксического анализа.
DateTimeFormatter анализирует текст в два этапа. На этапе 1 он анализирует текст в различные поля даты и времени в зависимости от конфигурации. На этапе 2 он преобразует проанализированные поля в объект даты и/или времени.
Атрибут ResolverStyle управляет этапом 2. Это перечисление , имеющее три возможных значения:
- СНИСХОДИТЕЛЬНО – разрешает даты и время снисходительно
- ИНТЕЛЛЕКТУАЛЬНОЕ – интеллектуальное разрешение дат и времени
- СТРОГО – строго определяет даты и время
Теперь давайте запишем проверку данных с помощью DateTimeFormatter напрямую:
public class DateValidatorUsingDateTimeFormatter implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingDateTimeFormatter(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { this.dateFormatter.parse(dateStr); } catch (DateTimeParseException e) { return false; } return true; } }
Далее давайте добавим модульный тест для этого класса:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.US) .withResolverStyle(ResolverStyle.STRICT); DateValidator validator = new DateValidatorUsingDateTimeFormatter(dateFormatter); assertTrue(validator.isValid("2019-02-28")); assertFalse(validator.isValid("2019-02-30"));
В приведенном выше тесте мы создаем DateTimeFormatter на основе шаблона и локали. Мы используем строгое разрешение для дат.
Контрольные показатели
Прежде чем мы завершим эту статью, давайте рассмотрим некоторые результаты тестирования, которые помогут нам проанализировать, какой из вышеупомянутых методов лучше всего подходит для нашего варианта использования.
6.1. Простой бенчмарк
Во-первых, мы используем простой подход. Мы выбираем одно строковое значение – для нашего теста мы используем Integer.MAX_VALUE . Затем это значение будет проверено на всех наших реализациях:
Benchmark Mode Cnt Score Error Units Benchmarking.usingCoreJava avgt 20 57.241 ± 0.792 ns/op Benchmarking.usingNumberUtils_isCreatable avgt 20 26.711 ± 1.110 ns/op Benchmarking.usingNumberUtils_isParsable avgt 20 46.577 ± 1.973 ns/op Benchmarking.usingRegularExpressions avgt 20 101.580 ± 4.244 ns/op Benchmarking.usingStringUtils_isNumeric avgt 20 35.885 ± 1.691 ns/op Benchmarking.usingStringUtils_isNumericSpace avgt 20 31.979 ± 1.393 ns/op
Как мы видим, наиболее дорогостоящими операциями являются регулярные выражения. После этого – наше основное решение на основе Java.
Кроме того, обратите внимание, что операции с использованием библиотеки Apache Commons по большому счету одинаковы
6.2. Усовершенствованный контрольный показатель
Давайте используем более разнообразный набор тестов для более репрезентативного эталона:
- 95 значений являются числовыми (0-94 и Целое число.MAX_VALUE )
- 3 содержат числа, но все еще неправильно отформатированы — ‘ x0 ‘, ‘ .005′, и ‘ -11 ‘
- 1 содержит только текст
- 1-это null
После выполнения тех же тестов мы увидим результаты:
Benchmark Mode Cnt Score Error Units Benchmarking.usingCoreJava avgt 20 10162.872 ± 798.387 ns/op Benchmarking.usingNumberUtils_isCreatable avgt 20 1703.243 ± 108.244 ns/op Benchmarking.usingNumberUtils_isParsable avgt 20 1589.915 ± 203.052 ns/op Benchmarking.usingRegularExpressions avgt 20 7168.761 ± 344.597 ns/op Benchmarking.usingStringUtils_isNumeric avgt 20 1071.753 ± 8.657 ns/op Benchmarking.usingStringUtils_isNumericSpace avgt 20 1157.722 ± 24.139 ns/op
Самое важное различие заключается в том, что два наших теста, решение для регулярных выражений и основное решение на основе Java, поменялись местами. Из этого результата мы узнаем, что выбрасывание и обработка исключения NumberFormatException , которое происходит только в 5% случаев, оказывает относительно большое влияние на общую производительность
Таким образом, мы можем сделать вывод, что оптимальное решение зависит от наших ожидаемых входных данных
Из этого результата мы узнаем, что выбрасывание и обработка исключения NumberFormatException , которое происходит только в 5% случаев, оказывает относительно большое влияние на общую производительность. Таким образом, мы можем сделать вывод, что оптимальное решение зависит от наших ожидаемых входных данных.
Кроме того, мы можем с уверенностью заключить, что для оптимальной производительности следует использовать методы из библиотеки Commons или метод, реализованный аналогичным образом.
Количество цифр в целочисленном числе
Для методов, обсуждаемых здесь, мы рассматриваем только положительные целые числа. Если мы ожидаем каких-либо отрицательных входных данных, то мы можем сначала использовать Math.abs(число) перед использованием любого из этих методов.
2.1. Решение На основе строк
Возможно , самый простой способ получить количество цифр в Integer – это преобразовать его в String и вызвать метод length () . Это вернет длину Строки представления нашего числа:
int length = String.valueOf(number).length();
Но это может быть неоптимальным подходом, так как этот оператор включает выделение памяти для строки для каждой оценки . JVM должен сначала проанализировать наш номер и скопировать его цифры в отдельную Строку , А также выполнить ряд различных операций (например, сохранение временных копий, обработка преобразований Юникода и т. Д.).
Если у нас есть только несколько чисел для оценки, то мы можем явно пойти с этим решением – потому что разница между этим и любым другим подходом будет пренебрегаться даже для больших чисел.
2.2. Логарифмический Подход
Для чисел, представленных в десятичной форме, если мы возьмем их логин в базе 10 и округлим его, то получим количество цифр в этом числе:
int length = (int) (Math.log10(number) + 1);
Обратите внимание, что log 10 какого-либо числа не определено. Итак, если мы ожидаем каких-либо входных данных со значением , тогда мы можем проверить и это
Логарифмический подход значительно быстрее, чем подход на основе String , поскольку ему не нужно проходить процесс преобразования данных. Это просто включает в себя простой, простой расчет без какой-либо дополнительной инициализации объекта или циклов.
2.3. Повторное Умножение
В этом методе мы возьмем временную переменную (инициализированную в 1) и будем непрерывно умножать ее на 10, пока она не станет больше нашего числа. Во время этого процесса мы также будем использовать переменную length , которая будет отслеживать длину числа:
int length = 0; long temp = 1; while (temp <= number) { length++; temp *= 10; } return length;
В этом коде строка temp совпадает с записью temp = (temp << 3) + (temp << 1) . Поскольку умножение обычно является более дорогостоящей операцией на некоторых процессорах по сравнению с операторами сдвига, последние могут быть немного более эффективными.
2.4. Деление на две степени
Если мы знаем о диапазоне нашего числа, то мы можем использовать вариацию, которая еще больше сократит наши сравнения. Этот метод делит число на степени двух (например, 1, 2, 4, 8 и т. Д.):
Этот метод делит число на степени двух (например, 1, 2, 4, 8 и т. Д.):
int length = 1; if (number >= 100000000) { length += 8; number /= 100000000; } if (number >= 10000) { length += 4; number /= 10000; } if (number >= 100) { length += 2; number /= 100; } if (number >= 10) { length += 1; } return length;
Он использует тот факт, что любое число может быть представлено сложением степеней 2. Например, 15 можно представить в виде 8+4+2+1, которые все являются степенями 2.
Для 15-значного числа мы бы провели 15 сравнений в нашем предыдущем подходе, который мы сократили до 4 в этом методе.
2.5. Разделяй и властвуй
Это, возможно, самый громоздкий подход по сравнению со всеми другими, описанными здесь, но излишне говорить, этот самый быстрый , потому что мы не выполняем никакого типа преобразования, умножения, сложения или инициализации объекта.
Мы получаем наш ответ всего в трех или четырех простых утверждениях if :
if (number < 100000) { if (number < 100) { if (number < 10) { return 1; } else { return 2; } } else { if (number < 1000) { return 3; } else { if (number < 10000) { return 4; } else { return 5; } } } } else { if (number < 10000000) { if (number < 1000000) { return 6; } else { return 7; } } else { if (number < 100000000) { return 8; } else { if (number < 1000000000) { return 9; } else { return 10; } } } }
Подобно предыдущему подходу, мы можем использовать этот метод только в том случае, если мы знаем о диапазоне нашего числа.
Использование Регулярных Выражений
Одним из способов выполнения нашей проверки является использование регулярных выражений. Чтобы ознакомиться с регулярными выражениями, пожалуйста, ознакомьтесь с этой статьей .
Прежде всего, давайте определим регулярное выражение для каждой из требуемых групп символов. Поскольку регулярные выражения фиксированы, нет необходимости оценивать их при каждом запуске, поэтому мы скомпилируем их, прежде чем сравнивать с ними :
private static final Pattern[] inputRegexes = new Pattern; static { inputRegexes = Pattern.compile(".*.*"); inputRegexes = Pattern.compile(".*.*"); inputRegexes = Pattern.compile(".*\\d.*"); inputRegexes = Pattern.compile(".*#$%^&*()\\-_=+\\\\|\\};:'\",<.>/?].*"); }
Кроме того, мы должны создать простой метод, который мы будем использовать, чтобы проверить, соответствует ли наша строка | условиям:
private static boolean isMatchingRegex(String input) { boolean inputMatches = true; for (Pattern inputRegex : inputRegexes) { if (!inputRegex.matcher(input).matches()) { inputMatches = false; } } return inputMatches; }
2.1. Одно Регулярное выражение
Предыдущий пример довольно удобочитаем и позволяет нам легко использовать только некоторые шаблоны, если это необходимо. Но в случае, когда мы заботимся только о выполнении всех условий, гораздо эффективнее использовать одно регулярное выражение.
Таким образом, нам не понадобится статический блок для инициализации и компиляции всех наших многочисленных выражений. Кроме того, не было бы необходимости перебирать их все и находить, какие совпадения, а какие нет.
Все, что нам нужно сделать, это объявить наше регулярное выражение:
String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)" + "(?=.*?#$%^&*()\\-_=+\\\\|\\};:'\",<.>/?]).*$";
А затем скомпилируйте и сравните его:
@Test public void givenSingleRegex_whenMatchingCorrectString_thenMatches() { String validInput = "Ab3;"; assertTrue(Pattern.compile(regex).matcher(validInput).matches()); }
Есть несколько вещей, на которые мы должны обратить внимание в отношении нашего регулярного выражения. Во-первых, мы использовали положительный внешний вид ( ?=X ) для каждой группы символов
Это означает, что мы ожидаем , что X будет найден после начала строки (помеченной ^ ), чтобы соответствовать, но мы не хотим идти в конец X , скорее мы хотим остаться в начале строки
Во-первых, мы использовали положительный внешний вид ( ?=X ) для каждой группы символов . Это означает, что мы ожидаем , что X будет найден после начала строки (помеченной ^ ), чтобы соответствовать, но мы не хотим идти в конец X , скорее мы хотим остаться в начале строки.
Еще следует отметить, что на этот раз мы не использовали или для групп букв, а вместо этого использовали \p{Lu} и \p{Ll} . Они будут соответствовать любой букве (в нашем случае заглавной и строчной соответственно) из любого языка, а не только английского.
Повторы
Допустим, вы пишете программу, в которой вас просят проверить, много ли чисел простое; не один раз Хотя наша программа, приведенная выше, оптимизирована для этого алгоритма, существует другой способ, специально подходящий для этой ситуации: Prime Sieve.
Вот основная идея:
- Предположим, что каждое целое число, большее или равное 2, простое.
- Начните с начала списка, если число простое, вычеркните все множители этого числа из списка. Они не простые.
- Переходите к следующему числу, если оно вычеркнуто, пропустите его — оно не простое. Если оно не вычеркнуто, оно должно быть простым, вычеркните его кратные.
- Повторение
Посмотрим, что это значит. Рассмотрим список:
2 простое … вычеркните это кратно. Наш список теперь выглядит так: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 …
Вы можете понять, почему 2 — единственное простое число. Делая это с помощью 3, мы вычеркиваем 6 (уже вычеркнуто), 9, 12 (уже вычеркнуто), 15 и т. Д. В конце концов, ваш список будет выглядеть так: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 …
А наши простые числа остались: (2,3,5,7,11,13,17,19,23,29, …). В коде вы можете отслеживать этот список как массив. Это означает, что вы настроите «сито» через n чисел, но восполните его при повторном вызове функции, так как она вернет мгновенное значение, является ли число простым или нет. Вот как это будет выглядеть. Конечно, вы можете отредактировать это самостоятельно в соответствии со своими потребностями:
простое число java
Как определить простое число в Java
0.00 (0%) votes
Бенчмаркинг
Теперь, когда у нас есть хорошее понимание потенциальных решений, давайте проведем простой бенчмаркинг всех наших методов с использованием жгута Java Microbenchmark (JMH) .
В следующей таблице показано среднее время обработки каждой операции (в наносекундах):
Benchmark Mode Cnt Score Error Units Benchmarking.stringBasedSolution avgt 200 32.736 ± 0.589 ns/op Benchmarking.logarithmicApproach avgt 200 26.123 ± 0.064 ns/op Benchmarking.repeatedMultiplication avgt 200 7.494 ± 0.207 ns/op Benchmarking.dividingWithPowersOf2 avgt 200 1.264 ± 0.030 ns/op Benchmarking.divideAndConquer avgt 200 0.956 ± 0.011 ns/op
Решение на основе String , которое является самым простым, также является самой дорогостоящей операцией, поскольку это единственная операция, которая требует преобразования данных и инициализации новых объектов.
Логарифмический подход значительно более эффективен по сравнению с предыдущим решением, поскольку он не требует преобразования данных. И, будучи однострочным решением, это может быть хорошей альтернативой подходу на основе String – .
Повторное умножение включает в себя простое умножение, пропорциональное длине числа; например, если число состоит из пятнадцати цифр, то этот метод будет включать в себя пятнадцать умножений.
Однако самый следующий метод использует тот факт, что каждое число может быть представлено степенями двух (подход, аналогичный BCD), и сводит то же самое к 4 операциям деления, поэтому он еще более эффективен, чем первый.
Наконец, как мы можем заключить, наиболее эффективным алгоритмом является многословная реализация “Разделяй и властвуй” , которая дает ответ всего в трех или четырех простых операторах if. Мы можем использовать его, если у нас есть большой набор данных чисел, которые нам нужно проанализировать.
Использование Регулярных Выражений
Теперь давайте использовать регулярное выражение -?\d+(\.\d+)? для сопоставления числовых Строк , состоящих из положительного или отрицательного целого числа и поплавков.
Само собой разумеется, что мы определенно можем изменить это регулярное выражение, чтобы идентифицировать и обрабатывать широкий спектр правил. Здесь все будет просто.
Давайте разберем это регулярное выражение и посмотрим, как оно работает:
- -? – эта часть определяет, является ли данное число отрицательным, тире ” – “ищет тире буквально и знак вопроса” ? ” отмечает свое присутствие как необязательное
- \d+ – при этом выполняется поиск одной или нескольких цифр
- (\.\d+)? – эта часть регулярного выражения предназначена для идентификации чисел с плавающей запятой. Здесь мы ищем одну или несколько цифр, за которыми следует точка. Знак вопроса, в конце концов, означает, что эта полная группа является необязательной.
Регулярные выражения-это очень широкая тема. Чтобы получить краткий обзор, ознакомьтесь с нашим учебником по API регулярных выражений Java .
А пока давайте создадим метод, используя приведенное выше регулярное выражение:
private Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); public boolean isNumeric(String strNum) { if (strNum == null) { return false; } return pattern.matcher(strNum).matches(); }
Теперь давайте рассмотрим некоторые утверждения для приведенного выше метода:
assertThat(isNumeric("22")).isTrue(); assertThat(isNumeric("5.05")).isTrue(); assertThat(isNumeric("-200")).isTrue(); assertThat(isNumeric(null)).isFalse(); assertThat(isNumeric("abc")).isFalse();