Другое

Как проверить, является ли строка числом в Java

Узнайте несколько способов проверки, является ли строка числом в Java перед парсингом. Блоки try-catch, регулярные выражения, Apache Commons Lang и подходы с BigDecimal с примерами кода. Освойте числовую валидацию в Java.

Как проверить, является ли строка числовой в Java перед ее парсингом?

Чтобы проверить, является ли строка числовой в Java перед ее парсингом, можно использовать несколько подходов, включая блоки try-catch с методами парсинга, регулярные выражения или библиотеки утилит, такие как Apache Commons Lang. Наиболее распространенным и надежным методом является использование блоков try-catch с методами Integer.parseInt(), Double.parseDouble() или аналогичными методами парсинга, которые выбрасывают NumberFormatException, когда строка не является числовой. Для более сложных случаев можно использовать BigDecimal или шаблоны регулярных выражений для проверки формата строки перед попыткой ее парсинга.

Содержание

Использование блоков try-catch с методами парсинга

Наиболее прямой подход - использование встроенных методов парсинга Java внутри блока try-catch. Этот метод использует тот факт, что методы парсинга, такие как Integer.parseInt() и Double.parseDouble(), выбрасывают NumberFormatException, когда входная строка не является допустимым числом.

Вот базовая реализация для проверки целых чисел:

java
public static boolean isNumericInteger(String str) {
    try {
        Integer.parseInt(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Аналогично для значений типа double:

java
public static boolean isNumericDouble(String str) {
    try {
        Double.parseDouble(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Этот подход прост и эффективен для большинства случаев использования. Согласно Java Code Geeks, “Java предоставляет методы, такие как Integer.parseInt() и Double.parseDouble(), для преобразования строк в числовые значения. Мы можем использовать эти методы для проверки, является ли строка числовой.”

Вы можете создать более комплексный метод, который обрабатывает несколько числовых типов:

java
public static boolean isValidNumber(Class<?> type, String numString) {
    try {
        if (type == int.class || type == Integer.class) {
            Integer.parseInt(numString);
        } else if (type == double.class || type == Double.class) {
            Double.parseDouble(numString);
        } else if (type == float.class || type == Float.class) {
            Float.parseFloat(numString);
        } else if (type == long.class || type == Long.class) {
            Long.parseLong(numString);
        } else if (type == short.class || type == Short.class) {
            Short.parseShort(numString);
        } else if (type == byte.class || type == Byte.class) {
            Byte.parseByte(numString);
        } else {
            return false;
        }
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Подход с использованием регулярных выражений

Регулярные выражения предоставляют мощный способ проверки числовых строк без reliance на обработку исключений. Этот подход может быть более эффективным для простых сценариев проверки и дает вам точный контроль над числовым форматом.

Вот несколько шаблонов регулярных выражений для разных числовых форматов:

Проверка целых чисел:

java
public static boolean isNumericIntegerRegex(String str) {
    return str.matches("-?\\d+");
}

Проверка double/десятичных чисел:

java
public static boolean isNumericDoubleRegex(String str) {
    return str.matches("-?\\d+(\\.\\d+)?");
}

Поддержка научной нотации:

java
public static boolean isNumericScientific(String str) {
    return str.matches("-?\\d+(\\.\\d+)?[eE][+-]?\\d+");
}

Комплексная проверка числовых значений:

java
public static boolean isNumericComprehensive(String str) {
    return str.matches("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
}

Как отмечено в результатах исследования, “Хотя регулярные выражения обеспечивают точность, они могут повлиять на производительность для очень длинных строк или сложных шаблонов. Рассмотрите альтернативные подходы, такие как анализ по символам или предопределенные парсеры числовых значений для оптимальной эффективности.”


Решения с использованием Apache Commons Lang

Библиотека Apache Commons Lang предоставляет удобные методы утилит для проверки числовых значений, которые автоматически обрабатывают различные крайние случаи.

Использование NumberUtils.isCreatable():

java
import org.apache.commons.lang3.math.NumberUtils;

public static boolean isNumericWithCommons(String str) {
    return NumberUtils.isCreatable(str);
}

Использование NumberUtils.isParsable():

java
public static boolean isParsableWithCommons(String str) {
    return NumberUtils.isParsable(str);
}

Разница между этими методами заключается в том, что isCreatable() может обрабатывать более сложные форматы, такие как научная нотация и шестнадцатеричные числа, в то время как isParsable() работает только с форматами, которые могут быть обработаны стандартными методами парсинга Java.

Согласно Java Code Geeks, “Класс Test содержит метод с именем isValidNumberWithCommons, который использует метод isCreatable из NumberUtils для определения, может ли строка быть преобразована в допустимое числовое значение.”

Для использования этих методов необходимо добавить зависимость Apache Commons Lang в ваш проект:

Maven:

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

Gradle:

gradle
implementation 'org.apache.commons:commons-lang3:3.12.0'

BigDecimal для сложных случаев

Для обработки очень больших чисел, научной нотации или точных десятичных значений BigDecimal является отличным выбором. Он может парсить широкий variety числовых форматов и предоставляет точные арифметические операции.

java
import java.math.BigDecimal;

public static boolean isValidBigDecimal(String str) {
    try {
        new BigDecimal(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

BigDecimal может обрабатывать случаи, которые другие методы парсинга могут упустить, такие как очень большие числа или сложная научная нотация. Как упоминается в статье Baeldung, “BigDecimal является частью пакета java.math Java и предназначен для управления десятичными значениями произвольной точности. Он способен парсить целые числа, десятичные дроби и даже числа в научной нотации.”

Для проверки целых чисел с использованием BigDecimal:

java
public static boolean isWholeNumber(String str) {
    try {
        BigDecimal bd = new BigDecimal(str);
        String bdStr = bd.setScale(0, RoundingMode.UP).toString();
        String intStr = bd.toBigInteger().toString();
        return bdStr.equals(intStr);
    } catch (NumberFormatException e) {
        return false;
    }
}

Рассмотрения производительности

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

Сравнение производительности:

Метод Заметки о производительности Лучше всего подходит для
Try-catch с парсингом Хорошо для большинства случаев, накладные расходы обработки исключений Простая проверка, когда исключения редки
Регулярные выражения Может быть медленнее для сложных шаблонов, но хорошо для простой проверки Проверка конкретного формата, где нужен контроль над шаблоном
Apache Commons Lang Оптимизированные методы библиотеки, хорошая производительность Производственный код с комплексными потребностями в проверке
По символам Самый быстрый для простых случаев, максимальный контроль Требования к высокой производительности с простыми числовыми форматами

Согласно результатам исследования с Reddit, “Каждый вызов ‘contains’ для каждого символа в худшем случае придется пройти по всей строке… Оптимальным способом было бы вызов Integer.parse или Double.”

Для сценариев с высокой производительностью рассмотрите этот подход проверки по символам:

java
public static boolean isNumericFast(String str) {
    if (str == null || str.isEmpty()) {
        return false;
    }
    
    boolean hasDigit = false;
    boolean hasDecimal = false;
    boolean hasExponent = false;
    
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        
        if (c == '-' || c == '+') {
            // Знак может быть только в начале или после показателя степени
            if (i > 0 && str.charAt(i - 1) != 'e' && str.charAt(i - 1) != 'E') {
                return false;
            }
        } else if (c == '.') {
            // Разрешен только один десятичный разделитель
            if (hasDecimal || hasExponent) {
                return false;
            }
            hasDecimal = true;
        } else if (c == 'e' || c == 'E') {
            // Разрешен только один показатель степени, должны быть цифры до и после
            if (hasExponent || !hasDigit || i == str.length() - 1) {
                return false;
            }
            hasExponent = true;
            hasDigit = false; // Сброс для цифр показателя степени
        } else if (Character.isDigit(c)) {
            hasDigit = true;
        } else {
            return false;
        }
    }
    
    return hasDigit;
}

Лучшие практики

При реализации проверки числовых строк в Java учитывайте эти лучшие практики:

  1. Выберите подходящий метод для вашего случая использования:

    • Используйте try-catch для простой проверки, когда исключения редки
    • Используйте регулярные выражения для проверки конкретного формата
    • Используйте Apache Commons Lang для производственного кода с комплексными потребностями
    • Используйте BigDecimal для требований к точности
  2. Обрабатывайте крайние случаи:

    • Null или пустые строки
    • Строки с начальными/конечными пробелами
    • Очень большие числа, которые могут превышать пределы примитивных типов
    • Научная нотация и другие сложные форматы
  3. Учитывайте требования к производительности:

    • Для частой проверки оптимизируйте скорость
    • Для редкой проверки отдавайте приоритет ясности кода и поддерживаемости
  4. Предоставляйте четкие сообщения об ошибках:

    • Когда проверка не проходит, рассмотрите возможность предоставления обратной связи о том, что пошло не так
    • Это особенно важно для проверки пользовательского ввода
  5. Тщательно тестируйте:

    • Тестируйте с допустимыми и недопустимыми входными данными
    • Тестируйте крайние случаи, такие как максимальные/минимальные значения
    • Тестируйте с разными числовыми форматами

Как предлагает Baeldung, “Для каждого входного значения, которое возвращает true с помощью этого метода, мы можем использовать NumberUtils.createNumber(String), что даст нам допустимое число. Метод NumberUtils.isParsable(String) проверяет, можно ли заданную строку распарсить или нет.”

Заключение

Чтобы эффективно проверить, является ли строка числовой в Java перед парсингом, у вас есть несколько надежных подходов на выбор. Метод try-catch с функциями парсинга, такими как Integer.parseInt() или Double.parseDouble(), является наиболее прямым и широко используемым подходом. Для более сложных потребностей в проверке регулярные выражения обеспечивают точный контроль над числовым форматом, в то время как Apache Commons Lang предлагает комплексные методы утилит, которые автоматически обрабатывают различные крайние случаи. BigDecimal является лучшим выбором для обработки очень больших чисел, научной нотации или точных десятичных значений.

При выборе метода проверки учитывайте свои конкретные требования, включая потребности в производительности, сложность числовых форматов, которые вам нужно поддерживать, и работаете ли вы с пользовательским вводом или внутренней обработкой данных. Для большинства приложений комбинация Apache Commons Lang для общей проверки и BigDecimal для требований к точности обеспечивает надежное решение, которое эффективно обрабатывает большинство случаев использования.

Источники

  1. Check if the Given String Is a Valid Number | Baeldung
  2. Java Program to Check if a String is Numeric | Vultr Docs
  3. Check If String Is A Valid Number In Java - Java Code Geeks
  4. How to check whether string is numeric in java without using exceptions? : r/learnjava
  5. Check if a given string is a valid number (Integer or Floating Point) in Java - GeeksforGeeks
  6. Java Interview: How to Check if a String Is Numeric in Java-Multiple Approaches | Medium
  7. Checking if a String is Numeric in Java - Programming
  8. Essential Guide: Verifying Strings as Numbers in Java
  9. How to Handle the NumberFormatException in Java | Rollbar
  10. 10 Quick Tips for Checking if a String Is Numeric in Java
Авторы
Проверено модерацией
Модерация