Проверить, является ли строка числовой в Java

1. Вступление

Часто при работе с _Strings нам нужно выяснить, является ли String _ допустимым числом или нет.

  • В этом руководстве мы рассмотрим несколько способов определения, является ли данная _Строка _ числовой ** , сначала с использованием простой Java, затем регулярных выражений и, наконец, с использованием внешних библиотек.

После того, как мы закончили обсуждение различных реализаций, мы будем использовать тесты, чтобы понять, какие методы являются оптимальными.

Давайте начнем с некоторых предварительных условий, прежде чем перейти к основному содержанию.

2. Предпосылкой

В последней части этой статьи мы будем использовать внешнюю библиотеку Apache Commons. Чтобы включить эту зависимость, добавьте следующие строки в pom.xml :

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</dependency>

Последнюю версию этой библиотеки можно найти по адресу https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.apache.commons%22%20AND%20a%3A%22commons-lang3 . % 22[Maven Central].

3. Использование простой Java

Пожалуй, самый простой и надежный способ проверить, является ли _String _ числовым или нет, - это проанализировать его с помощью встроенных методов Java:

, Integer.parseInt (String)

, Float.parseFloat (String)

, Double.parseDouble (String)

, Long.parseLong (String)

, new BigInteger (String)

Если эти методы не выдают NumberFormatException , то это означает, что синтаксический анализ был успешным и __String __is числовой:

public static boolean isNumeric(String strNum) {
    try {
        double d = Double.parseDouble(strNum);
    } catch (NumberFormatException | NullPointerException nfe) {
        return false;
    }
    return true;
}

Давайте посмотрим на этот метод в действии:

assertThat(isNumeric("22")).isTrue();
assertThat(isNumeric("5.05")).isTrue();
assertThat(isNumeric("-200")).isTrue();
assertThat(isNumeric("10.0d")).isTrue();
assertThat(isNumeric("   22   ")).isTrue();

assertThat(isNumeric(null)).isFalse();
assertThat(isNumeric("")).isFalse();
assertThat(isNumeric("abc")).isFalse();

В нашем _isNumeric () method мы просто проверяем значения типа Double , но этот метод также можно изменить, чтобы проверять Integer , Float , Long _ и большие числа, используя любой из методов синтаксического анализа, которые мы зачислили ранее ,

Эти методы также обсуждаются в ссылке:/java-string-conversions[Java String Conversions].

3.1. Проверка входов с помощью Scanner

java.util ‘s Scanner class, пожалуй, самый простой способ в простой Java для получения примитивных типов входных данных, таких как int , double и т. д. Он также предоставляет различные API-интерфейсы для проверки, является ли данный вход определенного типа или нет.

Например, следующие API проверяют, имеет ли ввод тип integer, long или float :

  • scanner.hasNextInt ()

  • scanner.hasNextLong ()

  • scanner.hasNextFloat ()

Эти API возвращают простые true или false в зависимости от типов ввода. Мы можем использовать эти API, чтобы убедиться, что следующий ввод имеет желаемый тип.

Следующий фрагмент проверяет, является ли ввод целым числом или нет:

try (Scanner scanner = new Scanner(System.in)) {
    System.out.println("Enter an integer : ");
    if (scanner.hasNextInt()) {
        System.out.println("You entered : " + scanner.nextInt());
    } else {
        System.out.println("The input is not an integer");
    }
}

Точно так же мы можем использовать другие API для проверки других типов.

4. Использование регулярных выражений

Теперь давайте использовать регулярное выражение _-? \ D (\. \ D)? для сопоставления числовых Strings _ , состоящих из положительного или отрицательного целого числа и чисел с плавающей точкой.

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

Давайте разберем это регулярное выражение и посмотрим, как оно работает:

  • -? - эта часть определяет, является ли данное число отрицательным, тире

« » Буквально ищет тире, а вопросительный знак « ? » Обозначает его присутствие в качестве дополнительного ** \ d - поиск одной или нескольких цифр

  • (\. \ d)? - эта часть регулярного выражения предназначена для определения чисел с плавающей точкой. Вот

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

Регулярные выражения - это очень широкая тема, и чтобы получить краткий обзор, перейдите по ссылке:/регулярные-выражения-java[эта связанная статья Baeldung]

А пока давайте создадим метод, используя приведенное выше регулярное выражение:

public static boolean isNumeric(String strNum) {
    return strNum.matches("-?\\d+(\\.\\d+)?");
}

Давайте теперь посмотрим на некоторые утверждения для вышеуказанного метода:

assertThat(isNumeric("22")).isTrue();
assertThat(isNumeric("5.05")).isTrue();
assertThat(isNumeric("-200")).isTrue();

assertThat(isNumeric("abc")).isFalse();

5. Использование Apache Commons

В этом разделе мы обсудим различные методы, доступные в библиотеке Apache Commons.

5.1. NumberUtils.isCreatable (String)

_https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html[NumberUtils] из Apache Commons предоставляет статический метод https://commons.apache . org/Proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html # isCreatable-java.lang.String-[NumberUtils.isCreatable (String)] , который проверяет, является ли _ действительным номер Java или не.

Этот метод принимает:

, Шестнадцатеричные числа, начинающиеся с 0x или 0X

, Восьмеричные числа, начинающиеся с 0

, Научная нотация (например, 1.05e-10)

, Числа, помеченные квалификатором типа (например, 1L или 2.2d)

Если предоставленная строка _null или empty/blank , то она не считается числом, и этот метод вернет false _ в этом случае

Давайте запустим несколько тестов, используя этот метод:

assertThat(NumberUtils.isCreatable("22")).isTrue();
assertThat(NumberUtils.isCreatable("5.05")).isTrue();
assertThat(NumberUtils.isCreatable("-200")).isTrue();
assertThat(NumberUtils.isCreatable("10.0d")).isTrue();
assertThat(NumberUtils.isCreatable("1000L")).isTrue();
assertThat(NumberUtils.isCreatable("0xFF")).isTrue();
assertThat(NumberUtils.isCreatable("07")).isTrue();
assertThat(NumberUtils.isCreatable("2.99e+8")).isTrue();

assertThat(NumberUtils.isCreatable(null)).isFalse();
assertThat(NumberUtils.isCreatable("")).isFalse();
assertThat(NumberUtils.isCreatable("abc")).isFalse();
assertThat(NumberUtils.isCreatable(" 22 ")).isFalse();
assertThat(NumberUtils.isCreatable("09")).isFalse();

Обратите внимание, как мы получаем _true _ утверждения для шестнадцатеричных чисел, восьмеричных чисел и научных обозначений в строках 6, 7 и 8 соответственно.

Также в строке 14 строка _ «09» turns false because предыдущего «0» указывает, что это восьмеричное число, а «09» _ не является действительным восьмеричным числом.

Для каждого ввода, которое возвращает _true с помощью этого метода, мы можем использовать https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#createNumber-java.lang .String -[ NumberUtils.createNumber (String) _ ], который даст нам правильный номер.

5.2. NumberUtils.isParsable (String)

Метод _https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#isParsable-java.lang.String-[NumberUtils.isParsable (String)] проверяет, является ли данная String _ анализируемой или нет.

  • Разборные числа - это те, которые успешно анализируются любым методом разбора, например Integer.parseInt (String) , Long.parseLong (String) , _Float.parseFloat (String) or Double.parseDouble (String) _ . **

В отличие от NumberUtils.isCreatable () , этот метод не принимает шестнадцатеричные числа, научные записи или строки, заканчивающиеся любым квалификатором типа, например _ 'f', 'F', 'd', 'D', 'l' or ' L»._

Давайте посмотрим на некоторые утверждения:

assertThat(NumberUtils.isParsable("22")).isTrue();
assertThat(NumberUtils.isParsable("-23")).isTrue();
assertThat(NumberUtils.isParsable("2.2")).isTrue();
assertThat(NumberUtils.isParsable("09")).isTrue();

assertThat(NumberUtils.isParsable(null)).isFalse();
assertThat(NumberUtils.isParsable("")).isFalse();
assertThat(NumberUtils.isParsable("6.2f")).isFalse();
assertThat(NumberUtils.isParsable("9.8d")).isFalse();
assertThat(NumberUtils.isParsable("22L")).isFalse();
assertThat(NumberUtils.isParsable("0xFF")).isFalse();
assertThat(NumberUtils.isParsable("2.99e+8")).isFalse();

В строке 4, в отличие от NumberUtils.isCreatable () , число, начинающееся со строки _ «0» _ , не считается восьмеричным числом, но является нормальным десятичным числом и, следовательно, возвращает значение true.

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

5.3. _StringUtils.isNumeric (CharSequence ) ___

Метод _https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#isNumeric-java.lang.CharSequence-[StringUtils.isNumeric (CharSequence)] _ строго проверяет для цифр Юникода. Это означает:

, Любые цифры с любого языка, которые являются цифрами Unicode, являются приемлемыми

, Так как десятичная точка не считается цифрой Unicode, это не

действительный , Ведущие знаки (положительные или отрицательные) также не принимаются

Давайте теперь посмотрим на этот метод в действии:

assertThat(StringUtils.isNumeric("123")).isTrue();
assertThat(StringUtils.isNumeric("١٢٣")).isTrue();
assertThat(StringUtils.isNumeric("१२३")).isTrue();

assertThat(StringUtils.isNumeric(null)).isFalse();
assertThat(StringUtils.isNumeric("")).isFalse();
assertThat(StringUtils.isNumeric("  ")).isFalse();
assertThat(StringUtils.isNumeric("12 3")).isFalse();
assertThat(StringUtils.isNumeric("ab2c")).isFalse();
assertThat(StringUtils.isNumeric("12.3")).isFalse();
assertThat(StringUtils.isNumeric("-123")).isFalse();

Обратите внимание, что входные параметры в строках 2 и 3 представляют числа __123 на арабском и деванагари соответственно. Так как они являются действительными цифрами Unicode, этот метод возвращает true __onon.

5.4. StringUtils.isNumericSpace (CharSequence)

Https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#isNumericSpace-java.lang.CharSequence-[ StringUtils.isNumericSpace(CharSequence) ]проверяет строго для цифр Юникод и/или пробела. Это то же самое, что и _StringUtils.isNumeric () _ , с той лишь разницей, что он также принимает пробелы, не только начальные и конечные пробелы, но также, если они находятся между числами:

assertThat(StringUtils.isNumericSpace("123")).isTrue();
assertThat(StringUtils.isNumericSpace("١٢٣")).isTrue();
assertThat(StringUtils.isNumericSpace("")).isTrue();
assertThat(StringUtils.isNumericSpace("  ")).isTrue();
assertThat(StringUtils.isNumericSpace("12 3")).isTrue();

assertThat(StringUtils.isNumericSpace(null)).isFalse();
assertThat(StringUtils.isNumericSpace("ab2c")).isFalse();
assertThat(StringUtils.isNumericSpace("12.3")).isFalse();
assertThat(StringUtils.isNumericSpace("-123")).isFalse();

6. Ориентиры

Прежде чем мы завершим эту статью, давайте кратко рассмотрим результаты тестов, которые помогут нам проанализировать, какие из перечисленных методов являются оптимальными:

Benchmark                                     Mode   Cnt    Score     Error  Units
Benchmarking.usingCoreJava                    avgt   20   152.061 ±  24.300  ns/op
Benchmarking.usingRegularExpressions          avgt   20  1299.258 ± 175.688  ns/op
Benchmarking.usingNumberUtils__isCreatable     avgt   20    63.811 ±   5.638  ns/op
Benchmarking.usingNumberUtils__isParsable      avgt   20    58.706 ±   5.299  ns/op
Benchmarking.usingStringUtils__isNumeric       avgt   20    35.599 ±   8.498  ns/op
Benchmarking.usingStringUtils__isNumericSpace  avgt   20    37.010 ±   4.394  ns/op

Как мы видим, наиболее дорогостоящая операция с регулярными выражениями, за которой следует базовое решение на основе Java. Все остальные операции, использующие библиотеку Apache Commons, в целом одинаковы.

7. Заключение

В этой статье мы исследовали различные способы выяснить, является ли _String _ числовым или нет. Мы рассмотрели оба решения - встроенные методы, а также внешние библиотеки.

Как всегда, реализацию всех приведенных выше примеров и фрагментов кода, включая код, используемый для выполнения тестов, можно найти по адресу over на GitHub .