Как проверить, является ли строка двоичной в java

Класс 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.

Вот основная идея:

  1. Предположим, что каждое целое число, большее или равное 2, простое.
  2. Начните с начала списка, если число простое, вычеркните все множители этого числа из списка. Они не простые.
  3. Переходите к следующему числу, если оно вычеркнуто, пропустите его — оно не простое. Если оно не вычеркнуто, оно должно быть простым, вычеркните его кратные.
  4. Повторение

Посмотрим, что это значит. Рассмотрим список:

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();
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: